ASP.NET MVC – How to Create View Models: Constructor, Factory Method, etc.

asp.net-mvcmodelprogramming practices

I'm trying to lead a charge for re factoring our rather bloated controllers.
We currently have a BaseModel from which all our other models inherit. The BaseModel contains things common to all pages, such as the page title, css files needed, current user.

Each constructor has a private method to construct a particular ViewModel (essentially a factory method)

BaseModel.cs

Class BaseModel {
    public string title {get; set;}
    public List<String> cssFiles {get;set;}
    // More Properties
}

HomeModel.cs

Class HomeModel : BaseModel {
    public List<News> LatestNews {get;set;}
}

ExtendedHomeModel.cs

Class ExtendedHomeModel : HomeModel {
    public List<RSSItem> Twitter {get;set;}
}

HomeController.cs

public ActionResult Index(int userid) {
    return View(MakeExtendedHomeModel(userid));
}

private ExtendedHomeModel MakeExtendedHomeModel(int userid) {
    var model = new ExtendedHomeModel();

    InitialiseBaseModel(model, userid);
    InitialiseExtendedBaseModel(model);

    model.Twitter = DomainModel.Twitter.GetLatestItems();
}

private HomeModel MakeHomeModel() {
    var model = new HomeModel();
    InitialiseBaseModel(model);
    InitialiseHomeModel(model);
}

private void InitialiseHomeModel(HomeModel model) {
    model.LatestItems = DomainModel.GetLatestItems;
}

private void InitialiseBaseModel(BaseModel model, int userid) {
    model.PageTitle = "Home"
    model.UserId = userid
}

So, my question is: what is the best way of initialising these kind of base models? As far as I can tell what the constructor essentially does is the factory method, and at the very least it should be moved out of the constructor.

However, I'm convinced there is a more elegant way of doing this. The main problem that I see is that the code is thoroughly depended on you calling the initialise methods in the correct order.
One idea I've had is to use constructors, passing necessary parameters down the chain as necessary. Are there any pitfalls to this approach I havent seen? (Bearing in mind I've only started asp mvc six months ago). Are there any better ways?

Thanks for reading

Best Answer

The pattern I have settled on for creating my view models is SomeViewModel is created by a static method (or instance method if appropriate) on SomeViewModelFactory. I don't inherit from base models for members that are duplicated. I use interfaces and external setter methods that operate on those interfaces to set the properties. This abstracts away the creation of the view model to a single function call for a single view model and one setter function called internally for each interface the view model implements. As you can tell, I prefer composition over inheritance in this case. To me, it is less complex and more reusable than inheritance.

You might be interested in Automapper if you are doing any mapping between your domain model for your database and your view models. Hope this helps spur on any ideas that may be laying dormant in your mind.

Edit: I forgot to mention that you can define extension methods on those interfaces to take inputs and do the setting on the object its self. This technique is called a "mixin". That way you don't need to create classes for your setter methods, they appear to you as instance methods on the viewmodel object.

Edit 2: To answer your first comment, that is up to you and your preferences. Personally, I like to stay consistent and I would just copy/paste the model into a new class and add the property. Then use the setter for the old class and just set that one property normally. Remember that there should be no logic in your view models; they should only know that they are holding data, not how that data is created.

Automapper is still being actively developed as far as I can tell. It's really more of a utility library rather than a full blown framework. It seems to be pretty mature to me, I've been using it at work with much success. You may have to write the code that goes from ViewModel to DomainModel for stuff like updating data in a database, but at least you won't have to do the DomainModel > ViewModel part. Automapper takes care of that very well.

Edit 3: Your concern about staying DRY is valid; however, I interpret that principle as don't repeat your logic (not data structure). Your view model is a support structure for your data that provides you the benefit of static typing in your view. Each view model is specific to a single view. Using inheritance for property reuse needlessly ties the view model of 2 separate views that just happen to be similar. If you use inheritance, changing the base view model has a ripple effect across all your views with view models that inherit from it. Maybe that is what you want, but you can get the same benefit by defining an interface for all view models that need it. If there is a change, this allows you to decide for each model if it should still implement that interface or if a new interface is needed.