In MVVM, with Entity Framework, what populates the view model? - c#

I'm writing a WPF desktop application. I'm trying to understand the MVVM flow of data. I'm using Entity Framework as a data access, and I'm using a code-first approach so I have my POCO entity classes that represent each SQL table.
With this configuration, it's my understanding that my model (M in MVVM) is my POCO entity class. My views (V in MVVM) are my WPF windows.
What populates my view models? Do I just make my EF queries inside my views, populating the view models? Do my view models perform their own querying (inside class constructor, perhaps)?

Typically the view is a WPF window and it's corresponding code behind. The view model is a simple class that is created to handle the data layer requirements for the specific view and to do the processing. It is common to use Commands in the XAML view on the controls and each command is bound to a command instance that is in the view model. The view model can be created by dependency injection or it can be passed into the constructor in the views code behind and it is stored as member/property in the code behind. Make sure to set the views data context to the instance of the view model so to allow binding to the properties and commands in the view model.
this.DataContext = new TheViewModelType();
The Entity Framework Plain Old CLR Objects are data models and the view should not typically know about these. The view model may have properties of the model types that the view can bind to for say Items controls and such. So in the view:
<ItemsControl x:Name="CarItems" ItemsSource="{Binding Vm.CarsCollection}"></ItemsControl>
So, since the view's DataContext is a instance of the view model type, the view controls may bind directly to properties in the view model. The example is the view model having a collection of Cars and the view model may call a service when needed to populate the Cars collection. Obviously the a Car is the model.
public MyViewModel( )
{
Cars = TheCarsDataLayerService.GetCars( );
}
private IObservable<Car> _cars;
public IObservable<Car> Cars
{
get { return _cars; }
set
{
if( _cars == value )
return;
_cars = value;
RasisePropertyChanged("Cars");
}
}
For the Cars service int the example, This may be a data layer repository or it could be a instance of the Entity Framework DbContext. So the view model can have a field of the DbContext derived type or a service of such and this can be passed into the constructor of the view model class or injected with dependency injection or maybe the service is a static factory or singleton that the view model just calls into to populate the its members with the data that the view is going to display to the user.
MVVM is a pretty basic design pattern that can be implemented in many different ways. Some developers will take the pattern to new heights and strictly obey many rules in which the components of the pattern communicate. Ultimately,using the pattern is much better than not using any pattern at all regardless of how it is implemented, as it will allow the code to scale much better and other developers might much more easily understand the code and expect certain things. Also, the MVVM pattern allows for WPF devs to unit test. When done well enough, the view models can be tested and since there is no code in the views code behind and the view doesn't do anything but display data that it doesn't even know about, testing the view model is good enough.

Strictly using your domain models as view models will eventually if not immediately cause you problems. Typically a domain model consists of raw data, it may or may not contain business operations, some may place that in a BusinessLayer manager class for example. But you VM ViewModel is strictly for the view, should exist only in the view project. Cluttering your domain with view related dropdowns etc... is not an appropriate place to put those "View" data sources.
So to put this in code terms, your view model can contain a property that references an instance of the domain model OR you could add every property that the view will expose. But by separating the ViewModel and Model (domain model) you are allowing the view to be able to expose/hide what it needs as well as convert some properties, for example an EntityFramework model may contain a string property but your view may want a strictly numeric representation of it on one screen while another may allow an edit as string property, point is your EF model (domain model) doesn't need to worry about those view issues.
Where do you create the VM?
The job of a controller is to interpret a request and determine the view and view model needed. So it would be in the controller that the VM is created using a EF domain model class (for an edit request as an example) as the source of the VM.

Related

Is the View in MVC supposed to know the about the Model Data?

I've researched about MVC for a while and similar questions like this and this.
They, however doesn't answer my question. In a lot MVC examples (Both ASP.NET MVC and JAVA MVC) They usually provide the Model with fields E.G (Name, Age etc) and then allow the view to "read" those fields.
But from what I've understood is that the View should not know about the Model, cause if the View does then it's not (correctly) encapsulated.
Pictures however shows that the View knows about the Model to display correct data.
If I understood correctly is that the Model can be business logic for a system and the View is not supposed to be connected to that.
Lets say that my Model fetch data from a database, then it's still my Model that is my business logic and not the database or am I thinking wrong?
So my questions is
Should the View know about the Model to use correct data?
Is the Controllers job to fetch data from E.G a database and create a Model from that, and the View should use the Model data for display?
What is Model Business Logic? (Please don't use fields to explain)
a lot of this is open to interpretation. There are a number of approaches and is down to which ever suits you best. My approach is below if its some help.
Should the View know about the Model to use correct data?
Yes. The view has a model import directive for it to bind to when it's rendered. If the view didn't know anything about the model it was accessing then how could it bind to the data.
Is the Controllers job to fetch data from E.G a database and create a Model from that, and the View should use the Model data for display?
No, the controller should no nothing about the implementation of the data layer. The controllers only job should be to invoke the services that it needs to build up the view model.
What is Model Business Logic? (Please don't use fields to explain)
Not to sure about the exact term "Model Business Logic". Model can be used to describe domain models or in this case View models. Business logic are operations you perform on business or domain model objects populated by some service.
The way how i handle ViewModels and business logic as you say is to separate out the domain model, e.g. Customer or Order in a separate dll and have those domain objects populated by a service. Then your View Model becomes a composite of domain model objects.
So in all.. the controller makes a call out to services that consume datalayers which in term return you populated domain objects. These can then be used to populate your view model which is then used by the view.
I've added below a very simplistic look at approach which will hopefully point you in the right direction.
public class MyController
{
[HttpGet]
public ViewResult GetCustomer(int customerID)
{
var myViewModel = new CustomerViewModel();
var myService = new MyServiceLayer();
var myCustomerDetails = myService.GetCustomerDetails(customerID);
myViewModel.Customer = myCustomerDetails;
return View("CustomerDetails", myViewModel);
}
}
public class CustomerViewModel
{
public CustomerDomainObject Customer { get; set; }
}
public class CustomerDomainObject
{
public string Name {get;set;}
}
public class MyServiceLayer
{
public CustomerDomainObject GetCustomerDetails(int customerID)
{
var myCustomer = new CustomerDomainObject();
var dataLayer = new MyDataLayer();
var myCustomerData = dataLayer.GetCustomerDetails(customerID);
var myDataRow = myCustomerData.Tables[0].Rows[0];
myCustomer.Name = myDataRow["Name"].ToString();
return myCustomer;
}
}
public class MyDataLayer
{
public DataSet GetCustomerDetails(int customerID)
{
//Execute proc etc...
return new DataSet();
}
}
In ASP.NET MVC you have strong typed views. This is a razor thing that let you access to your model properties easily when you are building your view. You will easily notice this since IntelliSense will work whenever you are trying to access a property like #Model.Name. If it should or not be strong typed, IMHO it just relay on what you need, there are not cons on using strong typed views. It will help you big time whenever you code your views, and you will have less runtime errors for sure.
For 'Model Business Logic' I would say that you can for sure have a lot of Logic in your model, but that is not as simple as it sounds. You will probably have to work with patterns and have small classes which responsible for one thing.
Look at this link: https://msdn.microsoft.com/en-us/library/hh404093.aspx
Generally speaking it's a good idea to completely separate the domain model from its view representation. Domain model contains the entire business logic, which can be quite complex. Also, the presentation layer usually requires extremely simplified objects (just data structures, without any business logic). Specific view technologies might apply heavy restrictions to the objects. Besides of that, we often change/aggregate domain objects to suit the final user specific needs (by creating specialized DTOs). Therefore, since presentation and domain layers are so distinct (and domain model should never depend on view), I often completely separate them. This allows to create a more supple design.

Where to convert entities/models to viewmodels in MVVM?

In MVC it's pretty straignforward:
Client makes a request, controller asks buiseness logic to do some fancy stuff, buiseness logic asks repository to return some data, then repository returns data and buiseness logic is responsible for converting data from entities to viewmodels, which are returned to the client.
In MVVM I'm pretty much lost, since the viewmodel itself is responsible for making requests to the buiseness logic, there is no "middle layer" like the Controller. I could implement mappers in the buiseness logic project but since viewmodels are responsible to ask buiseness logic for data, it would create circular reference.
So where do I have to make this "magic" happen?
I'm gonna try to give some context with a simple example.
Be aware that all the code below is conceptual only and written here and not in VS.
Think of your ViewModel as a wrapper for your model.
Your model is exposed by a property so you can bind to it or to it's properties from your view.
Your ViewModel :
public class SomeEntityViewModel : NotificationObject
{
private SomeEntity _someEntity;
public SomeEntity SomeEntity
{
get{ return _someEntity;}
set
{
_someEntity = value;
RaisePropertyChanged("SomeEntity");
}
}
}
Now lets assume you send a request to your server and await a response.
Let's also assume you have an higher object (like a parent ViewModel) which initiates your VM :
public class SomeEntityContainerViewModel : NotificationObject
{
public ObservableCollection<SomeEntityViewModel> Items;
public void async OnRequestNewEntity()
{
SomeEntity newEntity = await _someEntityService.CreateSomeEntityAsync();
var vm = new SomeEntityViewModel{ SomeEntity = newEntity};
Items.add(vm);
}
}
Your SomeEntityContainerView of which SomeEntityContainerViewModel is the DataContext :
<UserControl>
<Button Command="{Binding RequestNewEntityCommand}" />
<ItemsControl ItemsSource="{Binding Items}" />
</UserControl>
Your SomeEntityView of which SomeEntityViewModel is the DataContext :
<UserControl>
<TextBlock Text="{Binding SomeEntity.Name}" />
</UserControl>
In it's most simplistic design :
Your model needs to be "dumb", only data.
Your ViewModel is the closest equivalent to a Controller and it will handle the logic and it is the component that will wrap (not convert) your model in a view model.
In the example above we have some higher object a parent ViewModel which initiates our ViewModel.
That's equivalent to a Controller's scope which has other nested controllers under it in the DOM.
Based on the mvvm-light reference I am assuming a WPF app here.
I the 1st paragraph you mention your business logic (I will call it a service from here) is responsible for converting to the view model. I would say the service should have no knowledge of the view. So in that case the controller (or a mapper called by controller or model binder) would handle the mapping.
In MVVM (my opinion here while trying to draw a comparison for you) the ViewModel acts a lot like the controller as it goes and gets the model, maps and binds to an observable. It is then also the model that binds to the view (the view model that is often used in mvc).
So I think the trick here for you is to move where the mapping should occur. The services should not have any knowledge of the views. They are not coupled to the views then which is a good thing.
In MVVM the "business layer" that you refer to is the "model" - in fact anything after the viewmodel is considered part of the "model". However in any work I've ever done, I've always split this model into n-tier, usually with a controller style class that uses services to retrieve data entities from a data repository.
Where to convert entities/models to viewmodels?
You don't, strictly speaking. The viewmodels can contain the entities (i.e. the VM has an ObservableCollection of them), or a viewmodel can wrap an entity (useful in list controls where you may need to show options or execute actions on a per row basis).
The MVC approach to an entity is a bit dirtier than MVVM, you end up with a richer business model rather than a nice lean entity. In MVVM that "richness" is mostly split out and handled by the viewmodel, and you try and keep the data entity as simple as possible (yes you can include things like validation in the entity, but you should only do it when necessary, other times the validation should be taken care of in the VM or somewhere in the model).
Your question is the wrong way round. The view model represents the logic behind the users interaction with your application, so the question really should be "how does the view model acquire entities and models when user interaction requests them?". The answer is: "With a dependency injection framework, e.g. Ninject". This allows you to scope entities to pages in a WPF app, to web requests in an MVC or WCF app, to singletons in any external console utilities or to mocked objects in your testing framework...and all without your view models knowing or caring about how those entities or the services providing them are being created or work internally.

How to implement n-layer architecture in MVC?

I know this question has been asked before. I am only asking so that I can get a better explanation. In my webforms applications, this is how I implemented my projects. The solution had two projects. The first project contains Data Access and Business Logic. The first project is referenced in the second project. The aspx.cs files call the business logic class and the business logic class calls the data access class.
I am trying to follow the same approach in my MVC applicaiton. How would I implement that? Controller calls Model which in turn calls Business logic? This approach would add overhead right?
In reference to the direction the comments are taking this thread (this doesn't fit neatly into a comment):
The models folder that is created with a new MVC project is for View Models - they are classes to support views. These are not your business models or data models.
For instance, in a ViewModel that supports a view, you might have a enum property that renders to a dropdown:
public enum CustomerTypes
{
INDIVIDUAL = 0,
COMPANY
}
public class CustomerViewModel
{
public CustomerTypes Type { get; set; }
public string[] CustomerTypesSelectList { get; set; }
}
public class CustomerController : Controller
{
public ActionResult Edit()
{
var model = new CustomerViewModel();
model.CustomerTypesSelectList =
Enum.GetNames(typeof(CustomerTypesSelectList));
return View(model);
}
}
And with this you have some javascript in your view to populate a fancy drop down list with the items in CustomerTypesSelectList.
The UI-specific string[] property is a common construct of a ViewModel that gets stripped away when it gets converted to the business model or data model. The Controller would control the conversion (a.k.a. mapping), but probably rely on another class to implement the mapping that ties together the ViewModel and the business model.
To sum up, in an n-layer architecture:
The MVC Controller is not your business logic. Your business logic resides inside of various services and components that are called by the controller.
The Models folder contains ViewModels - classes that are meant to support the operation of the UI only.
The Controller calls a mapper to translate between ViewModels and business models when calling into the business layer.
Have your architecture with following things
Data access project - add ORM/ADO.net with repository and unit of work pattern. Repositories can be generated using T4 template from ORM
ViewModel project - have a separate project for Viewmodels (containing properties to be used by view).
Business layer - have classes which contains functions that access repositories from data access layer, join them if needed using LINQ and populate in Viewmodel and return view model object or view model collection to controller.
WEB Project -
Controller - access business layer functions using dependency injection and return view model to view
View - Access view mode returned by controller

Do I make viewmodels for each page?

I'm creating a game where I have a lot of different pages. For instance: loginpage, profilepage, playersfriendeditpage.
Do I create a ViewModel for each of them? They are all dealing with the model, "player", but in diffeent aspect. Whats common sense?
Well since a view model acts as interface to your model from your view, it makes sense that any time a view needs to modify a model differently than any other view has, you'll want a new view model.
In other words, even though various views may LOOK different, it's the interaction with the model/view model that dictates whether a new view model is necessary.
If your page contains a ton of stuff, it may make sense to break them up into sub VMs. I try to think of a ViewModel as just a class and like any other class, you don't want it to do EVERYTHING if it doesn't make sense to. If your page is logically broken up into a mini-views, then you should be able to easy encompass those needs in a sub-VM.
For example: say you have an edit page that contains all your info. Maybe the user information (name, address, phone #) is a VM, the work history is a VM and the hobbies section is a VM and your main VM basically does all of the stuff around it. You can use messaging and/or events to handle the communication needs.
ViewModels are useful when you want to create a model that contains an instance of another model. This is the case when you have a 1 to many relationship between one model and another (one table and another) and need to display both information on the same view, for example. Or not even 1 to many necessarily, but that's often the case.
If you have a drop down list that contains values populated from a table in a database, but your View should display all other information from a different model, for example, you would use a ViewModel in this example.
I would define a ViewModel as an abstraction of a view. The viewModel should contain properties and methods which provide the Data and behaviour that a view requires to function correctly.
Given this definition my instinct would be to provide a separate viewModel for each view as they are each likely to have their own unique behaviour.
The fact that all views depend on the same Player entity is an implementation detail and as has already been suggested this functionality should be moved into a base class that the other viewModels can derive from, something along the lines of this:
public abstract class ScreenViewModel : ViewModelBase // Implements INotifyPropertyChanged
{
private Player _currentPlayer;
public ScreenViewModel(IRepository<Player> playerRepository)
{
// Retrieve desired player from the repository.
this._currentPlayer = playerRepository.Find(...);
}
// This is an idea of the sort of thing you can do; derived viewModels
// do not need to worry about loading the player, they can just consume
// it and provide the screen specific behaviour.
protected Player CurrentPlayer
{
get { return _currentPlayer; }
}
}
I don't agree with the advice provided in the currently accepted answer as it is wrong; it is your views that should shape your viewModels not your database. The design of the database should have little or no bearing on the design of your viewModels. The whole point of having a viewModel between your view and your domain layer is to insulate your application from changes in the lower layers.
In fact, if you look at the example viewModel I have provided it is fairly well insulated from those sorts of changes. The Player would typically be exposed as a POCO (making it persistence ignorant) and the repository that provides access to those entities is hidden behind an interface.
This means I could change the way the database structure is implemented and these changes would be absorbed by the data layer (e.g. by changing the way Entity Framework maps the tables to the entities in the application) and the viewModel would require no changes. You could even change the persistence mechanism (I.E. save data to a custom file rather than a database) and as long as it mapped the data to the Player POCO and the new repository implemented the IRepository<Player> interface your viewModel would still work as expected, demonstrating that the database structure has little or no bearing on the design of your viewModels.
It depends on the way you design your database.
If you want all the fields to be in a same table you can keep them under the same view model and this is not the case with most of the cases because you wouldn't like to have any redundant information in your database and you want your database to be normalized. So you can structure your models depending on your database design so that your database has no redundant information.

ASP.NET MVC - Should I use the Repository Pattern to write ViewModels to the database or convert them to Models first?

In my ASP.NET MVC app, I have a fairly complex edit page which combines a number of models into one view.
I'm using the ViewModel pattern to combine all of this information and present one cohesive object to the View.
As an example, my ViewModel structure is something like this:
CompanyId
CompanyName
List<Employee> Employees
List<ContactMethod> ContactMethods
The Employee object has a number of basic properties, and a preferred contact method.
On the edit page, the user is given all of the employees of the company and they have the ability to add and remove (using javascript), as well as edit employee details. The ContactMethods list is used to populate the dropdown for each employee.
I've successfully translated my Models (read from the database) into this ViewModel and back again, so after an edit, I'm left with a ViewModel representing the current state of that company's employees.
I'm using a Repository pattern to communicate with the database, so my question is, should I call directly into the CompanyRepository, passing the ViewModel, or should I convert the ViewModel back into Model objects first before using the Repository to write them to the database?
In short, should the Repository know about my ViewModel objects?
I would convert the ViewModel back into Model objects first. I like keeping the dependency between my Web layer and Repository layers as loose as possible.
I don't think your Repository should know about your ViewModel, since that's a web level concept.
ViewModel is the model to the view (UI), so repository shouldn't know about the view model. Separating them will keep repository loosely coupled from the UI.
Use another layer like service layer, to encapsulate repository from the UI.
This layer also does the ViewModel - Model conversation and do respository call.
public class ServiceLayer
{
public void SaveModel(ViewModel viewmodel)
{
var model = viewModel.ToModel();
repository.Save(model)
}
}
I would agree with the previous answer of converting ViewModels back into "plain" Models, but would add that this task should probably be carried out by a separate service layer. This layer would be responsible for disassembling your ViewModels and acting appropriately.
This is essentially the definition of a service: something whose job is to carry out a logical unit of work that requires multiple models and/or complex logic.

Categories