Should each view model be handled by a single ViewModelLocator? - mvvm-light

I am starting to explore the MVVM light and start to design my different viemModels. I have browsed for long time to find out what I am looking for but I could not get it :-(.
One sample I have is based on a single MainViewModel, which is handled inside a ModelViewLocator. In most cases we will have more than one viewModel, so should all viewModels be defined in a single ViewModelLocator file or do I have to have one ViewModelLocator per view?
In other words do I need to get this :
MainViewModel -> MainViewModelLocator
PictureViewModel -> PictureViewModelLocator
Ok fine but sill one question:
let say that I have 3 viewModels that I have create as ViewModel1, 2 and 3
In ViewModelLocation, I have create same structure as the MainViewModel in order to create the instance of it and have create a main property to access Models instance.
The problem I have found is that If each of my Views corresponding to each viewModels is set to is own datacontext as ViewModelLocator.ViewModelx, the view instance is create at design time and it makes me trouble if during the constructor of my view I need to call an external class which get data from a WCF service. It generate an "instance creation error".
In an other hand if in each view I bind then NOT from ViewModelLocator.ViewModelx but instead as directly ViewModelx then I do not get that error and works better.
So what is the properway to do and the logic path :
1 - Does the MainViewModel should create all other viewModel's ?
2 - Does each View must be bound to it's own MainStatic propery in ViewModelLocator ?
3 - Does each View create their own Instance of ViewModel ?
The way I have done is that my View which return service data from an external class during ViewModel constructor creation works only if I bind it directly to the ViewModel, does it have trouble doing it so ?

Usually there is no need for multiple view model locators. The common way is to create one ViewModelLocator which you then add to Application.Resources in App.xaml so it's available to be used anywhere in the application. Just create a property in the ViewModelLocator for each ViewModel you're using.
Below is an example which is using the IoC container in MVVM Light 4 (beta) to instantiate view models. You could also do without the IoC container but in more complex scenarios it'll definitely simplify your code:
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<DetailsViewModel>();
}
public MainViewModel MainViewModel
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public DetailsViewModel DetailsViewModel
{
get
{
return ServiceLocator.Current.GetInstance<DetailsViewModel>();
}
}
}

Related

asp.net MVC 4 with Data Access Layer using Entity Framework 5?

In my project, i have first created my Data Access Layer using Entity Framework with the following projects in a single solution,
1.Domain Model - Entity Model (.edmx)
2.Services - Business Services, Dtos, Infrastructure(Configurator), Interfaces and Models(Repository)
Now the problem is, i want to connect this data access layer to my MVC project, i do not know how to make the data access layer projects to behave as the models for my mvc project. So can anyone tell me how to connect my data access layer into my controllers and views.. any references is appreciated. Thanks in Advance !
I think what you're asking is what's the best way for controllers to interact with your services and data layer?
One option is to use the mediator pattern, and decouple the services from the controllers.
There's a great implementation for ASP.NET MVC apps: ShortBus, also available on nuget that I've used in a number of projects, and so far it's worked great.
One of the nice things about ShortBus is it's support for dependency injection. In the example below, all the services are created with Ninject, and require the appropriate registration.
The basic idea is you define queries and commands that the controllers will use, and then add handlers to perform the actual work.
public class AddUser : ICommand<User>
{
public string Email { get; set; }
}
and then a handler:
public class AddUserHandler : ICommandHandler<AddUser, User>
{
private IDatabaseService _database;
private IEmailService _email;
public AddUserHandler(IDatabaseService database, IEmailService email)
{
_database = database;
_email = email;
}
public User Handle(AddUser command)
{
bool created = _database.CreateUser(command.Email);
if (created)
{
_email.SendWelcome(command.Email);
}
}
}
Then inside your controller, all you'd do is issue the command:
public class UsersController : Controller
{
private IMediator _mediator;
public UsersController(IMediator mediator)
{
_mediator = mediator;
}
public ActionResult Create(string email)
{
User user = _mediator.Send(new AddUser("foo#bar.com"));
}
}
The things I like about this pattern are:
Controllers don't need to know how to create a user. It issues a command, and the appropriate business logic handles it.
Each handler can require the services it needs. There's no need to pollute the controllers with services only used by a single action.
It's really easy to unit test. I use a mock, and only need to verify that _mediator.Send() was called with the correct parameters. Then to test the handler, I mock IDatabaseService and IEmailService and verify they are called correctly in the 2 cases.
Commands and queries can be reused, and again, the caller never needs to know what's required to handle the request.
As for the Views, I'd recommend ViewModels.
Each View gets it's own ViewModel, which holds whatever is required for showing that particular page. You'd then map your domain objects to their own individual ViewModels, possibly with AutoMapper.
What's nice about ViewModels is you can format the data appropriately (formatting a DateTime maybe), and then your Views don't need any special logic. If later you decide to update the DateTime format, you only need to change it in one place.
Create a (shared) interface to pass to the layer that's between the DAL and MVC, especially if you're unit testing. Use a repository pattern. Check it out here:
http://csharppulse.blogspot.com/2013/09/learning-mvc-part-5repository-pattern.html
This should get you going...

Asp.net mvc razor - Send data to main layout

I am newbie in asp.net mvc.
I created an asp.net mvc4 empty application and added an entity model to it.
I have a layout page which I want to display menu categories,header,footer vb.But how can I send the data contains one more entity object(last posts,categories,tags) to layout page ?
Thanks
If you want to pass data (coming from database I assume) to the layout view you are facing a scenario where you have data that is passed to every page in your application. So what I would do is create a base controller from which all your controllers will inherit:
public class BaseController : Controller
{
public LayoutModel model;
public BaseController()
{
// Here you will use some business logic to populate your Layout Model
// You might also consider placing this model into the cache to prevent constant fetching of data from the database on each page request.
model = _service.Populate();
ViewBag.LayoutModel = model;
}
}
As you can see I used the constructor of the base controller to fetch the data needed for your layout view. I made a property named model and used some business logic method called Populate (you need to write this yourself) to populate the model variable. Then I place the model into the ViewBag.
Once I have this set up then every controller I make in my solution needs to inherit from the base controller:
public class HomeController : BaseController
{
// Controller code here...
}
which means that every controller can now access the model property from the base controller.
From here you can use the ViewBag.LayoutModel on each view like this (declare a local variable at the top of the view and cast it into the underlying type):
#{
LayoutModel MenuModel = ViewBag.LayoutModel;
}
and then use it like this:
#MenuModel.SomeProperty
This is just one of the ways to do it but there are other less/more complex ways. You need to do some research on your own and see which technique fits you the best...

Clarity about helpers in MVC3?

Are helpers in MVC3 used in the controller as well as the views?
Is a helper the right place to put commonly used controller methods?
I want to create a common method to get all sub children IDs in a database and make sure it is in the right area. I just want to make sure I am putting my logic in the right area.
Thanks
You could implement a base Controller for that logic. Helpers, or extension methods, are good for when you don't want to change the interface for something.
The HtmlHelper is not available to the controller, because the controller should not be responsible for generating HTML, but the UrlHelper is available within the controller.
A method to get specific data from your database does not belong in your controller, or in a UrlHelper or an HtmlHelper. You should create a separate class for this logic, and then call the method on this class from within your controller. If you are using Dependency Injection, which I suggest, your controller code might look like this:
public class MyController
{
IMyDataUtil _dataUtil;
public MyController(IMyDataUtil dataUtil)
{
_dataUtil = dataUtil;
}
public ActionResult SomeAction(int parentId)
{
var childIds = _dataUtil.GetChildIds(parentId);
...
}
}
As you can see, this allows you to keep the data-access code in a class specifically designed for that purpose. The fact that this controller depends on that utility class is immediately obvious, and doesn't take that much more code than calling an extension method on a helper. Controllers that don't deal with that class's methods won't need to have it available.
On the other hand, if there are methods that are likely to be used by a bunch of different controllers, injecting this same data class into all of them may become cumbersome. In that case, you could:
Extend a base class that has an instance of the data-access class injected into it via method or property injection, and which then exposes it to sub-classes via a protected or public property, or
Create your own helper class that wraps the classes and methods you're likely to use in all your controllers, and inject that class so you only have one dependency for a variety of common functions, or
Combine steps 1 and 2.
If by "helpers" you're referring to things such as HtmlHelper then, no, these aren't used by the controller as in theory you could take your controllers and re-use them with an entirely different rendering engine (for example WPF) as the controller isn't responsible for rendering.
If you're talking about, as I think you are, helper classes/methods that manipulate your data ready for it to be put into a Model by a Controller and then handed off to a View for presentation, then you could consider a "business logic" layer. For example, if you were talking about (the ever typical) Bank Account example, you could have a:
public class BankAccountService
{
public IEnumerable<string> GetAllAccountIdsForCustomer(int customerId)
{
// Talk to the database here and retrieve the account id's for a customer
}
public string GetCustomerName(int customerId)
{
// Talk to the database here and retrieve the customer's name
}
}
Your controller would then:
public ActionResult AccountNumbers(int customerId)
{
var model = new AccountNumbersModel();
model.CustomerId = customerId;
model.AccountNumbers = BankAccountService.GetAllAccountIdsForCustomer(customerId);
return View(model);
}
Obviously in this example you'd need to have a class called AccountNumbersModel defined and you'd also probably want to consider using Dependency Injection to provide an instance of BankAccountService to your controller, but describing how to go about all that is kinda outside the scope of this answer.
The advantages this approach gives you are testability and separation, each piece of code is responsible for one task, and you reduce the complexity of each individual piece and make it easier to make changes without breaking things.
I want to create a common method to get all sub children IDs in a database and make sure it is in the right area. I just want to make sure I am putting my logic in the right area.
That sounds like a job for an ActionFilter.

Binding Model properties directly in View

I've found this text in Prism documentation. I'm starting on MVVM and I'm at lost. Can (should) I bind model properties in the view or I must create a viewmodel with a proxy property for every property in the model?
The model classes typically provide
property and collection change
notification events through the
INotifyPropertyChanged and
INotifyCollectionChanged interfaces.
This allows them to be easily data
bound in the view. Model classes that
represent collections of objects
typically derive from the
ObservableCollection class.
EDIT: Here is some extra info to help. I'm building a personal project from the ground up (so I'm designing the models too), this is the first time that I use MVVM and I want to learn properly.
My model is very hieraquical, having classes with list of more class with more list inside, building a complex tree of information. I was trying the "standard" MVVM approach, build the model with POCO and no notifications, and using List. Then building the ViewModel with proper notifications and using ObservableCollections.
The problem is, the way it is going, I'm almost reconstructing my whole model as a ViewModel AND having to keep the data synched between the to (the ObservableCollection to the List). Then I read that on the Prism docs and wondered if I should have all that trouble or just create a root ViewModel for logic and bind all the rest to the model itself.
It depends really, if your model already implements INotifyPropertyChanged and/or IError info you might want to bind right to the model property. However if you want to do special validation and other stuff that the model knows nothing about you add the property wrappers in your view model.
This article gives a good example of a hybrid: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
Often my MV properties look like this and thats quite normal:
public string Symbol
{
get { return Model.Symbol; }
set { Model.Symbol = value; this.NotifyOfPropertyChange(() => this.Symbol); }
}
I often do NOT implement INotifyPropertyChanged in the model and thus often I have to write the wrappers.
EDIT: In response to your additional information: It can be a bit tricky to to keep the collections and lists in sync. In your case what I would do is to create a view model for each model class, but NOT wrap all the properties just access them like this: {Bindng Customer.Name}. But of course you have to create a wrapper for the collections which contain view models. The Prism documentation is, as they say themselves, just guidance, if your scenario needs a different approach then this is fine.
Take a look at this code. I only wrap the collections and the properties I will access through the model. This gives you the best of both worlds. Then IF you need a special property that does not belong into you model you can add it to the view model (see the CustomerViewModel), or if you need special notification for a certain properties.
class CompanyViewModel{
public CopanyViewModel(Company c){
foreach(var customer in c.Customers)
Customers.Add(new CustomerViewModel(customer);
}
public Company Company {get;set;}
public ObservableCollection<CustomerViewModel> Customers {get;set;}
}
class CustomerViewModel{
public CustomerViewModel(Customer c){
Customer = c;
}
public Customer Customer {get;set;}
public Brush CustomerBackground{
get{
if(Customer.Active)
return Brush.Greeen;
else
return Brush.Red;
}
}
}
(This code might not work, I just typed it in here.)
Now, if you need changed notification for all models and all properties you have to either implement it in you model or in wrap all properties in a view model.

Multiple models sent to a single view instance

My terminology is probably way off here but basically I'm trying to pass multiple data models to a view. To help put the question in context, take this example:
Say I was making a blog. When I log in I want the home screen to display a list of all new unapproved comments, as well as a list of recently registered users, and a list of the most recently submitted blog posts.
Most discussions I've seen suggest strongly-typing the view page so it can be called with something like "return View(RecentComments)" and iterate through the comments in the view, or to cast the data model like "var NewUsers = (MembershipUserCollection) ViewData.Model". What I'm ideally after is the 'right', or at least a 'right-enough', way of passing multiple models while still maintaining appropriate logic separation.
One way is to create a new type that encapsulates both pieces of model data:
public class MyBigViewData {
public SubData1 SubData1 { get; set; }
public SubData2 SubData2 { get; set; }
}
public class SubData1 {
... more properties here ...
}
public class SubData2 {
... more properties here ...
}
Another way is to store the "main" model data as the strongly-typed data and store other data in the view data as dictionary items:
ViewData["username"] = "joe"; // "other" data
ViewData["something"] = "whatever"; // "other" data
ViewData["subdata1"] = new SubData1(...);
return View(myRealModelData);
The advantage of the second approach is that you don't need to do anything special at all: It works right out of the box.
What I've done in the past is written a class that contained instances of both the classes I will need on the view.
ie
public class City{
public Mall TheMall;
public School TheSchool;
}
Then your view will be strongly typed as City, and you will use Model.TheMall.Property and Model.TheSchool.Property to access what you need
EDIT
This is an example of what other posters mean by creating an object with both objects as fields/properties
Sadly, the only way to accomplish passing multiple objects is either by creating an object with both objects as fields/properties, or by using a weakly typed array.
The way to pass multiple models to a view is to create what we call a Form View Model which has your other models within it.
Then in your view you can pass the individual models contained in your Form View Model to the Partial Views responsible for rendering the data in said models.
Makes sense?
edit
btw: a form view model is simply a class. it's not a special type as may have been suggested by my answer.
In addition to my other answer, another way to do this would be not to strongly-type the view and master pages in the page directive, but instead make use of the generic type-based ViewData extensions from MVC Contrib. These extensions basically use the fully-qualified type name as the ViewData dictionary key. Effectively, the typing benefits are the same as the strongly-typed page approach, with less class overhead in terms of the number of view model classes required. Then in your actions you do
ViewData.Add<Car>(car);
ViewData.Add<LayoutAData>(layoutAData);
and in the views you do
<%= ViewData.Get<Car>().Color %>
and in the master page you do
<%= ViewData.Get<LayoutAData>().Username %>
You could cache these Get<> calls inline in the views to mitigate the cost of casting multiple times.
After working on a large ASP.NET MVC app, I found the approach that was most productive while minimizing runtime casting was based on using generics to mimic the nested structure of views. Essentially views get their own data type. Typically these are either domain objects, or collections of domain objects that include metadata. Generic versions of these types are available across all possible master pages, taking a type parameter that defines data relevant to the master page.
public class Car {
// can be used as a model
}
public class CarCollection: Collection<Car> {
public BodyTypes BodyType {get;set;}
public Colors Color {get;set;}
// can also be used as a model
}
public interface ILayoutModel<TLayout> {
TLayout LayoutModel {get;set;}
}
public class CarView<TLayout>: Car, ILayoutModel<TLayout> {
// model that can be used with strongly-typed master page
}
public class CarCollection<TLayout> : CarCollection, ILayoutModel<TLayout> {
// model that can be used with strongly-typed master page
}
public class LayoutAData {
// model for LayoutA.master
}
public class LayoutBData {
// model for LayoutB.master
}
It's also possible to invert the generic-ness, but since the view dictates the layout, the view data should dominate over the layout data in my opinion. LayoutA.master would derive from ViewMasterPage<ILayoutModel<LayoutAData>> and LayoutB.master would derive from ViewMasterPage<ILayoutModel<LayoutBData>>. This keeps the view data and the layout data separate, in a consistent, strongly-typed and flexible way.
Creating an object that can encapsulate your other objects is the best way to go. Otherwise you're stuck with a bunch of ugly ViewData tags in the controller and the view.
One thing no one seems to have mentioned is that in the original questioners example, it might make sense to create the view out of a series of child actions that handle their own area of functionality rather than making a mega view model. That way the components such as unnapproved messages etc can be reused.
This also gives better encapsulation.

Resources