Question

This question really has larger architectural implications and I welcome any input or suggestions on this:

I'm more of the Martin Fowler school of thought when it comes to OOP. I believe you should be able to directly render domain entities in the UI. If I have a Car entity, I should be able to render it to a webpage. The domain model is a crosscutting concern and not a layer. Treating the domain model as a layer leads to an anemic domain model. I don't believe in DTOs in an OOP architecture.

A view model for me is a way of composing the domain entities required in your view. It's not a DTO. I don't understand what the reasoning behind using a view model like DTO is though it seems like a common thing to do using automapper?

So using the metadata approach I put data annotations on my domain model to give any UI implementation hints on how to render and validate the entities. I like to have a richER domain model.

In MVC3 how can you accomplish this (specifically using the Display data annotation) with a resource file that resides in the UI layer? Is there a native implementation for this or do I need to get creative myself? Or have I gone wrong somewhere in my approach?

Was it helpful?

Solution 2

So I ended up putting a resourse file in the domain model and added a custom HiddenFieldAttribute so that I don't have to reference the MVC assembly in the domain model.

I still fundamentally dissagree that a view model is really a DTO and that the domain model should be constructed as a layer. I feel that architecting the application in this way creates abstractions that really have no value. If the domain model was truly a layer then we would build a set of logical interfaces from which to access it, and this we don't do. It's a cross cutting concern.

Thanks to olivehour for an interesting discussion and suggesting that it's okay to place resource file(s) in to domain model assembly.

OTHER TIPS

I disagree.

For one thing, some of the attributes you will use to specify how an entity property should be displayed on a web page come from the System.Web namespace, not the System.ComponentModel.DataAnnotations namespace. By putting these attributes on properties in your domain model, your domain model is taking a dependency on System.Web. For example, there is the [HiddenInput] attribute that tells MVC3 to render a field as input type="hidden". This is not in System.CompoenentModel.DataAnnotations.

Secondly, I don't believe you need data annotation attributes on your entity properties to have a rich domain model. A rich domain model comes from classes that wrap knowledge in a context. The client application should not need to know anything about the domain in order to use it. You achieve a rich domain model with classes, methods, and properties that describe knowledge using the ubiquitous language. DataAnnotations attributes don't lend themselves well to the ubiquitous language imo. And, your domain is more than just your entities. There are factories, services, and other patterns that you can use to build a rich domain model. A domain with only entities and metadata sounds anemic to me.

Thirdly, you may have an entity that should be rendered in different ways on your web site. When someone searches for a car, you may want to display just the make, model, year, and thumbnail photo. When someone clicks on the search result, you may want to display multiple photos, reviews, etc. If you were to use the UIHint attribute on an entity to tell the web ui how to render the car, you wouldn't be able to have different strategies for rendering the Car in different contexts.

Finally, yes, automapper is really great for DTOing your entities into viewmodels. It essentially lets you populate copies of the entity, disconnected from the domain, targeted for specific UI concerns. Here it is safe to use HiddenInput and UIHint attributes to tell MVC3 how to render data.

Response to comment 1

As far as UIHint, I mentioned it here because it has a special meaning with MVC3 EditorTemplates. In cases where a partial view involves receiving input, what is the composition of the view? Text fields, drop-down lists, and input elements that often correspond to entities and their properties in some aggregate root. You will therefore need some representation of the entities to encapsulate the data. Your DTO can be an aggregate root as well, with depth. You can have a root DTO with scalar properties (text/date/bool), navigation properties (drop-down list) and collection properties (ul/ol/table).

We create a corresponding viewmodels for many entities in an aggregate root, and implement them as views using EditorTemplates. If we ever want to switch to a different EditorTemplate, we can apply UIHint to a viewmodel property. Thus we can tell it to "render a location dto as a google map". Automapper can map navigational and collection properties to corresponding viewmodels, forming as complex a representation of your domain entities as you need for the user.

Forgive me if I misunderstand what you mean by flat dto.

Response to comment 2

A viewmodel dto can flatten out / denormalize some properties (using automapper), if your requirements call for it. For example, consider a University entity. It may have many names in many languages (translations), hinting at a UniversityName entity in the aggregate, with University having a collection of Names (1..n). Of those names, 1 may represent the OfficialName / NativeName, and another may represent the TranslatedName to the user's CurrentUICulture. Other entities in the collection may represent TranslatedNames that the user does not understand, and need not be bothered with.

If you have a view that is only interested in these 2 Names in the collection, you can promote them to first-class properties on the viewmodel:

public class UniversityViewModel
{
    public string OfficialName { get; set; }
    public string TranslatedName { get; set; }
    // ...other properties
}

This is a case where denormalizing part of the entity when converting to a viewmodel dto can make sense. Notice how the viewmodel is anemic -- a bare container for data transfer from a controller to a view. This is perfectly fine, and in fact, encouraged.

Answer to original question

To answer your original question, it helps if you think of your domain model & entities as a layer -- more specifically, a bottom layer. Layered software is easier to understand if you think about the various concerns in an application as having dependencies on other concerns. MVC3 is a presentation / UI layer, and will have dependencies on the layers beneath it -- one of those being your domain layer.

If you want to access a resource file in the UI from the domain layer, you are going in the opposite direction. You would be making a low layer depend on a higher layer. If your domain lib depends on the UI lib for a resource, and the UI lib depends on the domain for entities, you end up with a circular dependency. I think you could probably accomplish it using reflection if you needed to, but in that case, you would be fighting against the framework. MVC and .NET in general may not be the best choice for you if that is the case.

I actually think of resource files as a cross-cutting concern. Our application has i18n sprinkled throughout, and often we find we need the same language text resources in both the domain and the UI.

There is nothing wrong with putting a Display attribute on an entity. But if you want to use resources for it, then either put that resource in the domain layer, or if you feel it doesn't belong there, in a lower layer. That way it can be accessed by both the domain and the UI.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top