I am working on a large ASP.NET MVC Project(about 15 separate projects). We are using a Facade Design Pattern to call Business logic as well as other Projects.
Question: in MVC application is it a best practice to call a Facade from the ViewModel?
I am using single facade instances to call all the functions. I create a ViewModel for each Action and populate it with data from within the ViewModel. These results are making the ViewModel larger, but the Controller Action gets thinner because we are doing the work in the ViewModel now. In the ViewModel constructor I pass the facade instance and take what's needed from the business logic layer.
public class MyViewModel
{
private Facade _Facade;
public IEnumerable<SomeModel> Collection { get; set; }
public IEnumerable<SelectListItem> Years { get; set; }
public IEnumerable<SelectListItem> Quarters { get; set; }
public int SelectedYear { get; set; }
public int SelectedQuarter { get; set; }
public BottomUpForecastViewModel(EXFacade facade)
{
this._Facade = facade;
this.Years = GetFinancialYears();
this.Quarters = GetFinancialQuarters();
this.SelectedYear = DateTime.Now.Year;
this.SelectedQuarter = TimePeriods.GetQuarterNoForDate(DateTime.Now);
Collection = GetMonthlyCollection(SelectedYear, SelectedQuarter);// Take data from the _Facade(call facade)
}
}
public class MyController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult BottomUpForecast()
{
return View(new MyViewModel(facade));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult BottomUpForecast(MyViewModel model)
{
return View();
}
}
Is this good practice?
Do you have a suggestion for a better approach taking into consideration that we don't need to worry about Dependencies?
UPDATE : I found an interesting article about how to make controllers Lean "Put them on a diet": http://lostechies.com/jimmybogard/2013/12/19/put-your-controllers-on-a-diet-posts-and-commands/**
Your idea is correct. Perfectly acceptable to call business logic from View Model. I do it all the time.
Unfortunately, your current implementation is strongly coupled to concrete types. You could use a little abstract refactoring:
In stead, in your Business layer, create an Interface, IEXFacade to pass bind your object and pass to your ViewModel:
public interface IEXFacade
{
public IEnumerable<SomeModel> GetMonthlyCollection(int SelectedYear, int SelectedQuarter);
public IEnumerable<SelectListItem> GetFinancialYears();
public IEnumerable<SelectListItem> GetFinancialQuarters();
public int getSelectedYear();
public int getSelectedQuarter(DateTime dateTime);
}
and your EXFacade definition would look something like:
public class EXFacade : IEXFacade
{
private TimePeriods _timePeriods = new TimePeriods();
public int getSelectedYear()
{
return DateTime.Now.Year;
}
public int getSelectedQuarter (DateTime dateTime)
{
return _timePeriods.GetQuarterNoForDate(dateTime);
}
public IEnumerable<SomeModel> GetMonthlyCollection()
{
....
return MonthlyCollection;
}
public IEnumerable<SelectListItem> GetFinancialYears();
{
....
return MonthlyCollection;
}
public IEnumerable<SelectListItem> GetFinancialQuarters();
{
....
return MonthlyCollection;
}
}
Now your View Model would take IEXFacade and would be more tolerant of change
public class MyViewModel
{
MyViewModel(IEXFacade facade)
{
Years = facade.GetFinancialYears();
Quarters = facade.GetFinancialQuarters();
SelectedYear = facade.getSelectedYear();
SelectedQuarter = facade.getSelectedQuarter (DateTime.Now);
Collection = facade.GetMonthlyCollection(SelectedYear, SelectedQuarter);
}
//Keeping the Facade Object seems extraneous (unless I'm missing something)
//private Facade _Facade;
public IEnumerable<SomeModel> Collection { get; set; }
public IEnumerable<SelectListItem> Years { get; set; }
public IEnumerable<SelectListItem> Quarters { get; set; }
public int SelectedYear { get; set; }
public int SelectedQuarter { get; set; }
}
The goal is to de-couple dependence on your specific implementation of your EXFacade class by passing an interface. Now your EXFacade methods logic can change without breaking your view model. As long as the Interface (properties and signatures) remain the same.
Conclusion:
I'm not partial to calling logic directly from my ViewModel, as opposed to my Controller. But, it's often more convenient as it saves a step. Conversely, logic injected directly into your model is less obvious than if you consolidate it into your controllers. But the argument about "Fat Controllers" vs "Fat Models" is pretty even sided and I don't think either side is more correct.
What's more important is to understand that the Facade Pattern is meant to be an interface between your "Chatty" Logic Layer and your Presentation Layer. For the sake of Abstraction and de-coupling, the pattern calls for an Interface. As soon as you abstract your Facade with an Interface you can further de-couple by using an IOC container like NInject to Inject your Facade into your controllers or Models.
I strongly recommend using the Dependency Injection pattern in a large project like this.
You'll be breaking the MVC pattern if you put business logic in the ViewModel. It's controller's job to construct the view, not the view constructing itself by receiving depenencies.
The ViewModel should be ignorant of other layers(View and Controller), thereby promoting loosely coupled architecture.
If your ViewModel becomes too large, you can create helper methods or classes just for constructing the ViewModel.
public class MyController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult BottomUpForecast()
{
return View(this.GetMyViewModel());
}
private MyViewModel GetMyViewModel()
{
var viewModel = new MyViewModel()
{
Years = this.facade.GetFinancialYears();
Quarters = this.facade.GetFinancialQuarters();
SelectedYear = DateTime.Now.Year;
SelectedQuarter = this.facade.TimePeriods.GetQuarterNoForDate(DateTime.Now);
Collection = this.facade.GetMonthlyCollection(SelectedYear, SelectedQuarter);
}
return viewModel;
}
}
// Thin ViewModel
public class MyViewModel
{
public IEnumerable<SomeModel> Collection { get; set; }
public IEnumerable<SelectListItem> Years { get; set; }
public IEnumerable<SelectListItem> Quarters { get; set; }
public int SelectedYear { get; set; }
public int SelectedQuarter { get; set; }
}
Interesting discussion about this topic here: https://stackoverflow.com/a/1464030/1027250
The view model is a model for the view. It should contain data (model) and any logic required to move that data into and out of the view. It shouldn't know anything about any other layers. It shouldn't even depend on the controller, never mind anything below that. It's the job of the controller to populate that view model so the job of the controller to invoke the business logic.
Just to add to #Yorro post, MVVM actually uses this pattern where VM is responsible for all such activities. It will be preferred to use Controller for such actions in MVC.
Related
I have developed my first WPF applicationa (tryingt) to use MVVM. I'm still learning and would appreciate the following questions answered:
Should I keep TestReportItem class in Repository class library or move it to it's own class library?
My ViewModel does not reference a Model. It refererences the class TestReportItem. I display the TestReportItem using XAML and a datatemplate to access a string field "Title". Is this acceptable/best practice?
TestReportItem
public class TestReportItem
{
public string Title { get; set; } = string.Empty;
public string SubTitle { get; set; } = string.Empty;
public bool HasTable { get; set; }
public string Reference { get; set; } = string.Empty;
public bool HasAdditionalInformation { get; set; }
}
TestReportItemRepository
public interface ITestReportItemRepository
{
List<TestReportItem> GetAllTestReportItems();
TestReportItem GetByName(string testName);
}
XMLTestReportItemRepository
public class XMLTestReportTestStandardRepository : ITestReportItemRepository
{
private string _filePath;
public string FilePath
{
get { return _filePath; }
set { _filePath = value; }
}
public XMLTestReportTestStandardRepository(string sourceFilePath)
{
FilePath = sourceFilePath;
}
public TestReportItem GetByName(string testName)
{ ... }
public List<TestReportItem> GetAllTestReportItems()
{ ... }
MVVM is a rule of thumb and not a dogma; meaning its really flexible. Originally MVVM was based off of the three tiered data organization system. View/Business layer/DB layer. And in a sense, it is just that.
Should I keep TestReportItem class in Repository class library or move it to it's own class library?
Whether your classes reside with the main project or in an external class library is up to the design. If the design calls for reuse between different projects, then yes extract it. Otherwise being external does not add any value except in separation of work.
Remember that an external library is in a sense a different namespace to structure your code.
My ViewModel does not reference a Model. It refererences the class TestReportItem.
As to TestReportItem it is a Model. Just because it has/may have methods and operations is moot. If one needs create partial class files where the model esque properties are contained in one partial and the operations et all are in another partial are fine and one achieves separation. But that is optional
datatemplate to access a string field "Title". Is this acceptable/best practice?
Does Title get derived or generated by its being in the class. If it does, then yes, if not, place Title on the main VM and extract/build it in the getter of Title.
I am trying to understand and implement different UI patterns in .NET to see the pros and cons and where they suite best.
I understand the main concept but I was creating an app and a question appeared.
Say we have a class Customer, which represents the core Information of a customer.
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
public string PhoneNumber { get; set; }
}
Now, if I create a WebView or WebForm to show all customers I can use this class to set as source f.e. to a DGV, being able to show all properties above.
But then I want to show for example a View/Form with the Revenue history of each customer.
So there is a class CustomerRevenue like
public class CustomerRevenue
{
public Revenue ActualYearExpectedRevenue { get; set; }
public IList<Revenue> RevenuePerYearList { get; set; }
public decimal ActualYearProjectedRevenue => CalculateYearProyection();
public decimal CalculateYearProyection(int year)
{
var daysInYear = DateTime.IsLeapYear(year) ? 365 : 366;
var actualYearRevenue = RevenuePerYearList.SingleOrDefault(x => x.Year == year);
var dayNumber = DateTime.Now.DayOfYear;
var projection = ((actualYearRevenue.Amount * daysInYear) / dayNumber);
return projection;
}
}
Here, to set RevenuePerYearList we need some time, since let's say we sell a lot and have a huge list of sells with huge lists of articles, so the calculation needs some time.
So now my question:
Should I then have "concrete" classes for each view/model with the data I want to show, i.e. here I would have apart of Customer class, say a CustomerRevenueModel
public class CustomerRevenueModel
{
private readonly CustomerRevenue _customerRevenue = new CustomerRevenue();
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
public CustomerRevenue CustomerRevenue
{
get { return _customerRevenue; }
}
}
}
which has (maybe) different properties, so I need to load this "heavy" properties when needed
or
should I stay with only one class (I mean, a customer always has a revenue) and leave the properties "empty"?
The first option makes me have a lot of classes, one for each view/form I want to show data for (maybe being able to reuse some models in various views/forms) but keeps all clean and in a valid state. And also each class can have it's own logic (domain logic - DDD)
The second option is less classes, less code, but some way I end having a huge (God) class, with all the properties a Customer has and all it's logic (methods). I load only the ones I need, but this appears really bad to me.
The third option is to have the big class with all properties and methods as my (domain)model, and create a "ViewModel" (which contains no methods, only props) each time I need to show sth. like above , using it as source for my GridView. This is the solution with more classes and code (big class + ViewModels + (maybe) DTOs), but also the more organized and SOLID design to my eyes... Here the use of a Mapper like AutoMapper would really help, mapping between objects
But this is the part I'm confused about...
Are these "ViewModels" a bad pattern using MVC or MVP?
Are this the same as the VM in MVVM? Which I Think not, since I've understood VM in MVVM like a "template", but what I talk about appears to me more like DAOs??
Or they don't have nothing to do, are just DAOs
I think I am a bit confused about all the different meanings of Model, ViewModel etc, in the different design patterns.
I am hardly trying to understand right MVC,MVP,MVVM and DDD and I think sometimes I am mixing terms...?
First, try to not "mix" things from different patterns, ViewModels are for MVVM, and you NEED ViewModels if you want to implement MVVM (ASP.Net MVC uses something called ViewModels, but it is not the same than the ViewModels in MVVM design pattern)
The ViewModel is like a model for the View. The ViewModel work is to "convert" the Model(s) to something the View can understand.
You can have one o more models (or none) and use it in the ViewModel, you have a ViewModel for each View.
In your example (a datagridview) you can have a model that will represent the data in a datagridview, a DTO if you want, and you can have a property in the ViewModel, a List and you will fill with data loaded from the database. In the View, you will bind that property (the list) to the dgv datasource.
Think that the ViewModel is something like the code behind of the view, but you are working with properties and commands that will be binded to controla in the view.
Update
I've managed to create something that is satisfactory. You can see the relevant parts of the code here on PasteBin. If there is there something that I could improve please let me know. I've got a nagging feeling this isn't very efficient.
Clarification
While it certainly seems to work with static dependencies as suggested by d_z, I was hoping, to avoid instantiating objects not utlilized, that I could use something similar to this:
public class HomeController : Controller
{
[Dependency]
protected IBaseData ActionData { get; set; }
public ActionResult Index()
{
return View(ActionData);
}
public ActionResult About()
{
return View(ActionData);
}
}
The data in the IndexData and AboutData instances in reality aren't static. The instance properties are set with data from a database. The DbProvider is injected into these classes.
In the end what I want is to minimize the memory footprint and database accesses.
Original
Let's say we have the following basic controller (with corresponding views):
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
We also have two classes with the same interface:
public class IndexData : IBaseData
{
public string Name { get; set; }
public string Index { get; set; }
public IndexData()
{
Name = "Index";
Index = "This is an Index instance";
}
}
public class AboutData : IBaseData
{
public string Name { get; set; }
public string About { get; set; }
public AboutData()
{
Name = "About";
About = "This is an About instance";
}
}
What I'd like is for Unity to inject an instance of one of these classes, depending on which action is executed, into the corresponding view. I've tried to get my head around how to achieve this but I'm stumped. Is this even possible?
What you are requesting makes little sense. Dependency Injection is about injecting (design time) behavior (a.k.a. services). What you are trying to do however is to inject runtime data. So this is not a task that yout IoC container should handle.
Next the view should be completely ignorant of any dependency injection. The controller should return all data that the view needs from its action method. Make sure that your About and Index action methods return the proper instance.
To register several mappings for a type in Unity you have to create named registration like this:
myContainer.RegisterType<IBaseData, IndexData>("Index");
myContainer.RegisterType<IBaseData, AboutData>("About");
So after this in your actions you can resolve an instance accordingly:
Index:
IBaseData data = myContainer.Resolve<IBaseData>("Index");
About:
IBaseData data = myContainer.Resolve<IBaseData>("About");
Or for static dependencies it works like this:
[Dependency("Index")]
IBaseData data { get; set; }
Take a look here and here for details
I'm developing a new MVC site for my company & kind of confused as how to create mapping from Domain/POCO objects to ViewModel classes [contains validation] & vice versa. Here's an sample example.
My domain class [just to keep it simple I'hv omitted other properties]:
public partial class Glossary
{
public int Id { get; set; }
public string GlossaryItem { get; set; }
public string Definition { get; set; }
}
my ViewModel class inside my MVC app's model folder [with corrosponding validation]:
public class GlossaryModel
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[Required(ErrorMessage = "Please enter a GlossaryItem")]
public string GlossaryItem { get; set; }
[Required(ErrorMessage = "Please enter a Definition")]
public string Definition { get; set; }
}
my Automapper configuration for DTO to Domain Model:
protected override void Configure()
{
CreateMap<GlossaryModel, Glossary>();
//....... etc
}
My controller's action method for editing an item:
public class GlossaryController : Controller
{
IGlossaryRepository _glossaryRepository;
IMappingService _mappingService;
public GlossaryController(IGlossaryRepository glossaryRepository, IMappingService autoMapperMappingService)
{
_glossaryRepository = glossaryRepository;
_mappingService = autoMapperMappingService;
}
// .... etc
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult Edit(GlossaryModel glossaryModel)
{
if (ModelState.IsValid)
{
var glossary = _mappingService.Map<GlossaryModel, Glossary>(glossaryModel);
if (glossaryModel.Id <= 0)
_glossaryRepository.Add(glossary);
else
_glossaryRepository.Edit(glossary);
_glossaryRepository.Save();
TempData["message"] = string.Format("{0} has been saved", glossaryModel.Definition);
return RedirectToAction("All");
}
return View(glossaryModel);
}
//....etc
}
And it's working fine, but my question is... Now say I need an action that will list down all glossary items like..
public ActionResult All()
{
var allItems = _glossaryRepository.Glossary;
if (allItems.Count() == 0) return View(new List<GlossaryModel>());
// **The below line is the reverse mapping one**
var allItemsModel = _mappingService.Map<IEnumerable<Glossary>, IEnumerable<GlossaryModel>>(allItems);
return View(allItemsModel);
}
But now I need automapper to convert from Domain objects to DTO [from List(Glossary) to List(GlossaryModel)], just opposite of the Edit method, to push the data to the view. So do I again need to map the opposite binding in the automapper config...!! like
protected override void Configure()
{
CreateMap<GlossaryModel, Glossary>(); // Added before for DTO to Domain object
CreateMap<Glossary, GlossaryModel>();// Added for Domain object to DTO
//....... etc
}
Is it a good design to bind both ways? or there's better solution I'm missing, Please help
Thanks,
Sanjay
Jimmy Bogard also asked the same question. But there was enough demand for it that direct support has been added for simple cases like you've listed. In fact, in this answer Jimmy also suggested that there's nothing wrong with it if it works for you. A simple example is:
protected override void Configure()
{
CreateMap<GlossaryModel, Glossary>()
.ReverseMap();
//....... etc
}
Note that ReverseMap doesn't work for more complex mappings. See this answer for more details.
Automapper was build to Domain to ViewModel (Domain to DTO in the manner in which you've described it) mapping
Summed up well by #Marius' answer here What is wrong with two-way mapping?
In some medium sized projects I've used two way mapping and for larger projects I use Domain To View Model mapping and then used a CQRS system for sending the ViewModel values to the underlying persistence store.
When it comes down to it, it is up to you how you choose to use Automapper and what Architectural decisions make sense to you.
The world will not stop rotating if you do 2 way mapping.
I want to implement MVP pattern for my application.
MVP Passive View actually. So I came to a problem, it's easy one,
but can't decide which path should I take, so
I want to ask you guru's, how to properly work with MVP and display rich UI.
I mean, let's assume we need to display some data, and customer wants it to be TreeView.
There is requirement, that if user select different treenode, then the application updates itself with
new data or something like that.
At this point, i'm not sure how to implement View.
(All view logic goes to presenter)
I don't think that it is a good idea, to expose WinForms class
ISomeForm : IView {
//Presenter will take control of this TreeView.
TreeView Host {
get;
}
}
or exposing my data models
ISomeForm : IView {
//View knows how to display this data
List<MyDataNodes> Items {
get;
set;
}
}
or using other View interfaces.
ISomeForm : IView {
//Presenter knows what Views presenter should display.
List<IDataView> Items {
get;
set;
}
}
Any suggestions?
I would go with the View Interfaces.
In WPF MVVM, the more view separation I have, the easier it is to manage the UI/Logic interaction along the way.
I had to solve this problem using a MVC pattern. You could expose the TreeView as you suggested in your first example. Then the presenter could subscribe some events of the TreeView. But if you go this way your presenter will probably have to subscribe a lot of events of differents controls on your form. I have chosen to have a single event on the form that sends messages to the controller (in my case). The messages are represented as a class and can have any information you need. This is how my message looks:
public class MvcMessage
{
public object Source { get; private set; }
public MessageType MessageType { get; private set; }
public Type EntityType { get; private set; }
public IList InvolvedItems { get; set; }
public int NumAffected { get; set; }
public EventArgs SourceEventArgs { get; internal set; }
/// <summary>
/// Name of property who changed its value. Applies to models implementing INotifyPropertyChanged.
/// </summary>
public string PropertyName { get; set; }
public MvcMessage(object source, MessageType messageType, Type entityType)
{
this.Source = source;
this.MessageType = messageType;
this.EntityType = entityType;
}
public void Reroute(Type newEntityType)
{
MvcMessage reroutedMessage = (MvcMessage)MemberwiseClone();
reroutedMessage.EntityType = newEntityType;
Controller.NotifyAll(reroutedMessage);
}
}
... where MessageType is a enum containing a lot of common commands and requests.
My IView interface then defines the event like this:
public delegate void ViewEventHandler(MvcMessage message);
public interface IView : IViewPage, IWin32Window
{
event ViewEventHandler ViewEvent;
...
}
You should go more along the lines of the two latter examples; the view shouldn't expose WinForm-ish details to the presenter. See this answer for details on handling exactly your problem with TreeView updating - especially item 5.