Search code examples
c#downcast

Downcast Domain Model to ViewModel


I have a domain model that looks like this:

public class Procuct {
    string Name {get;set;}
    double Price {get;set;}
}

I have a repository that gets some item like so:

public Domain.Product GetProduct(int id) {
    // (maps from my ORM model to my domain model)
    return ProductMapping.MapProduct(dataService.GetProductEntity(id));
}

I like this because now I have domain models I can work with wherever I need.

In MVC, I want to use this model, with a few extras, so I have a ProductViewModel:

public class ProductViewModel : Domain.Product {
    public ViewBase Base {get;set;} // standarized helper stuff in here
}

In my controller, I want to grab a domain object from the repository, and return it as the viewmodel type (where I can then add the Base):

public ActionResult ShowProduct(int productID) {

    var model = new ProductViewModel();
    model = repository.GetProduct(productID) AS ProductViewModel;
    model.Base = new ViewBase() { /* settings here */ };

    return View(model);
}

The Smell

This seems like it should work well, but I have a smell about this line that I don't like:

model = repository.GetProduct(productID) AS ProductViewModel;

Apparently downcasting like this tends to be indicative of a less-than-stellar inheritance setup, but I'm not sure how to approach it. Is this generally acceptable if the downcast is to a "light" derived object, or am I doing something particularly wrong here?

What's the correct way to get a domain model into a derived viewmodel?

Further Note

At first I had set up my viewmodel like this:

public class ProductViewModel {
    public Domain.Product Product {get;set;}
    public ViewBase Base {get; set;}
}

... which actually makes this whole thing very easy because I can just get the domain model and apply it to the property. My issue with this is that I can't it wreaks havoc on the client-side and naming with the UI framework I'm using - far, far easier to have the properties at the "model level" (for lack of better term)


Solution

  • Most of the time, UI requirements are very different from Domain requirements. I would create an additional mapping from your domain model to your view model. You may argue that there is some duplication, but as I mentioned above - your view model should be very different from your domain model. In theory, they serve different purposes and should contain different things.

    If you feel that the mapping is too "boilerplate", then use a framework like AutoMapper.

    https://github.com/AutoMapper/AutoMapper