ASP.NET MVC - M V C Responsibilities - asp.net-mvc

I am probably over analyzing here, but with all the reading I have done on MVC, there seem to be so many opinions on how to do things.
Is there a "Best Practices" site or document out there that defines the responsibility of each piece of MVC?
The few questions I have, keep in mind I am using the EF/Repository&UnitOfWork/Service pattern are:
1) How to get the validation results (error messages, etc) of Domain Objects and Business Rules from the Service Layer to the View Models?
2) I am using Domain Objects and a Service Layer that does all the Business Logic, then I send the Domain Objects to the controllers and let them (via AutoMapper) convert them to View Models for the views. What other types of things are the responsibility of the controller? Is the following code OK? Is this too much logic in the controller?:
public ActionResult SomeAction()
{
var model = Mapper.Map<DomainObject, ViewModel>(service.QueryReposForData());
model.SomeCollectionForSelectList = Mapper.Map<IEnumerable<DomainObject>, IEnumerable<ViewModel>>(service.QueryReposForSelectListData());
return View(model);
}
I don't think that the only thing in a controller is one line that returns a view with an object graph mapped to view models?
3) I think it is OK to have properties on the ViewModels that can indicate to a view if something can be hidden for example and then perform that logic in the view? Example:
#if(Model.DisplaySomething)
{
<div>Something to show</div>
}
else
{
<div>Something else to show</div>
}
4) I was thinking of having my services return some sort of TransactionResult object back to the controllers on writes to make it the responsibility of the service to handle the transaction. So I would have an aggregate service that would start a transaction (UnitOfWork) do what ever it needed to do and then return this TransactionResult that could have error messages? I don't think I should make the controller responsible for managing the transaction, but rather have it just pass in a view model mapped to a domain object to the service and let it act on it?
5) Also, how much of ActionFilter's do you want to use? I know it is a huge extensibility point, but I often find myself trying to stuff all of the model creation into a filter.

Just opinions here based on how we work.
We keep our Controllers so skinny they are anorexic, in almost every case.
As for ViewModels, we follow the pattern of having a ViewModel for every view. The Controller loads it up with anything it needs, and kicks it off. From there, the ViewModel drives everything. In our world, the ViewModel is tied directly to the view and contains no code that would/could be used in other parts of the application. It interacts with any part of the larger 'Model' (service layer, etc) that it needs to and packages stuff up for the View to consume.
For your #3 example, I'd say absolutely yes - it's the way we use our ViewModels.
Again, none of this is gospel - just my take on how we handle it.

Excellent questions!
1) How to get the validation results (error messages, etc) of Domain
Objects and Business Rules from the Service Layer to the View Models?
I use EntityFramework in the back-end and implement IValidatableObject both on my models and my entities. On models, I perform cross-field validation, while on entities, I perform cross-entity validations.
2) I am using Domain Objects and a Service Layer that does all the
Business Logic, then I send the Domain Objects to the controllers and
let them (via AutoMapper) convert them to View Models for the views.
What other types of things are the responsibility of the controller?
Is the following code OK? Is this too much logic in the controller?:
This code is perfect. Controllers gather data, transform data into models and feeds them into a view.
3) I think it is OK to have properties on the ViewModels that can
indicate to a view if something can be hidden for example and then
perform that logic in the view? Example:
Yes, this is exactly what a ViewModel is meant for. To capture all data AND logic required for your view to render.
4) I was thinking of having my services return some sort of
TransactionResult object back to the controllers on writes to make it
the responsibility of the service to handle the transaction. So I
would have an aggregate service that would start a transaction
(UnitOfWork) do what ever it needed to do and then return this
TransactionResult that could have error messages? I don't think I
should make the controller responsible for managing the transaction,
but rather have it just pass in a view model mapped to a domain object
to the service and let it act on it?
I struggled with this a bit in my projects. In the end, I moved the SaveChanges method of EntityFramework to the front-end. This allows me to build a transaction in the front-end and then commit it once. Every method in my ApiController which performs an update, create or delete will also do a SaveChanges.
I use ApiControllers as a layer of abstraction between my back-end and actual Controller classes. To elaborate, my application both uses normal Controllers (HTML) and ApiControllers (REST aka Web API). Both types of controllers share a common interface for retrieving data.
Example: http://pastebin.com/uL1NGGqH
The UnitOfWork still resides in my back-end behind a facade. I just expose the SaveChanges to the front-end. Side-effects such as ValidationExceptions are either handled by ASP.NET MVC automagically or captured in custom ActionFilters.
5) Also, how much of ActionFilter's do you want to use? I know it is a
huge extensibility point, but I often find myself trying to stuff all
of the model creation into a filter.
I only used a handful of ActionFilters in the large MVC project I am currently working on. These ActionFilters are mostly used to enforce security and to translate Exceptions (such as ValidationExceptions) to JSON-format so my client-side validation framework can handle it.
Off-topic: You can never over analyze. Asking yourself these fundamental questions of MVC makes you better grasp the concepts of MVC and makes you a better developer in general. Just make sure you don't do it too much in the boss' time ;)

Same here:
base controllers with common actionfilters
Validation is done using DataAnnotation and model validation within the controller.
tiny controllers with injected wrapped context or specific service layer
Automapper mapping ViewModels/EF Pocos.
I don't really bother about implementing UnitOfWork or explicitly using transactions since EF4 automatically creates (if it does not exist) a new transaction for all the changes done within a SaveChanges (http://msdn.microsoft.com/en-us/library/bb896325.aspx. I just have a generic interface exposing the DbSets of the Context as IQuerable and the Add/Delete/Find methods.
But as said it's all personal.

Related

MVC Pattern - Is this the correct approach for Repository / Unit of Work

I have been doodling and reading and just want to ensure the approach I am taking is correct. I am using MVC5 with EF, implementing the Repository and Unit of Work patterns.
EntityModel -> <- SomeRepository
SomeRepository -> <- SomeController
SomeController -> SomeViewModel
SomeViewModel -> SomeView
SomeView -> SomeController
SomeController -> <- SomeRepository
etc ..
In the controller I am planning on using something like AutoMapper to map the ViewModel to the EntityModel (and vice versa) which can then be passed to my repository / view.
Also, with this approach I am not 100% sure where my business logic should go. For instance, if I have an EntityModel for products and I wanted to add a GetAssociatedProducts method, would this go against the EntityModel or should another tier be introduced so the EntityModel is just a straightforward mapping class to the DB?
Should the ViewModel contain any logic at all? i.e Creating a Dictionary to populate a dropdown on the view based on values from the EntityModel?
I am trying to avoid the issues associated with just starting to code without thinking to much into how which is the reason for this question.
Note: I am also implementing IoC with Autofac but I don't think that's relevant at this point (saying just in case it is).
Well, you're already thinking too much.
First, since you specifically mention MVC, let me just say that the vast majority of what you're talking about is not MVC. MVC stands for Model-View-Controller. In the strictest sense, your model is the haven of all business logic for your application. The controller merely connects your model to your view, and your view merely presents the data to the client in a readable format.
Despite its name, ASP.NET MVC does not truly follow the MVC pattern. You could call it Microsoft's take on MVC. The controller and views track pretty closely (though there is some very noticeable and repugnant bleed-over, such as ViewBag). But, the "model" bit is very unclearly defined. Since, Entity Framework is integrated, most latch on to the entity and call this the model, but entities are really bad models. They're just (or at least should just be) a programmatic representation of a database table: a way for Entity Framework to take data from your table rows and put it into some structure that lets you get at it easily.
If you look at other MVC implementations such as Ruby on Rails or Django, their "model" is more of a database-backed factory. Instead of the class simply holding data returned from the database, it is itself the gateway to the database for that type. It can create itself, update itself, query itself and its colleagues, etc. This allows you to add much more robust business logic to the class than you can or should with an "entity" in C#. Because of that, the closest you can get a true MVC model is your domain or service layer, which isn't really factored in at all by default in ASP.NET MVC.
That said, though, if you're implementing a repository / unit of work pattern with Entity Framework, you're probably making a mistake. Entity Framework already does this so you don't have to. The DbContext is your Unit of Work and each DbSet is a repository. Any repository you create, dimes to dollars, will simply end up proxying your repository methods to methods on your DbSet, which is your first sign that something's not right. Now, that's not to say that a certain amount of abstraction isn't still a good idea, but go with something like a service pattern instead: something lightweight and flexible that will truly abstract logic instead of just creating a matryoshka doll of code that will only serve to make your application harder to maintain.
Finally, your view model (which is actually a rip from the MVVM pattern) should simply be whatever your view needs it to be. If your view needs a drop down list, then your view model should contain that. Whether your view model should generate it, is a slight different question that depends on the complexity of the data involved. I don't think your view model should know how to query a database, so if you need to pull the data from a database then you should let the controller handle that and just feed it to the view model. But, if it's something like a list of months, a enum structure, a numerically static list, etc., it might be appropriate for the view model to have the logic to construct that list.
UPDATE
No, they are actually implementing a repository. I'm not sure why in the world the introductory MVC articles on MSDN advocate this, but as one who fell into the same trap early on, I can say from personal experience, and many other long-time MVC developers will tell you the same, you don't want to actually follow this advice. Like I said, most of your repository methods end up just proxying to Entity Framework methods, and you end up having to add a ton of boilerplate code for each new entity. And, the further you go down the rabbit hole, the harder it is to recover, leading inevitably to some major refactoring once you finally grow tired of the repetitive code.
A service pattern is a lot simpler. There may still be some proxying for things like updates and deletes, where there's very little unique from one entity to another, but the real difference will be seen with selects. With a repository, you'd do something like the following in your controller:
repo.Posts.Where(m => m.BlogId = blog.Id && m.PublishDate <= DateTime.Now && m.Status == PostStatus.Published).OrderByDescending(o => o.PublishDate).Take(10).ToList();
While with a service you would do:
service.Posts.GetPublishedPostsForBlog(blog, limit: 10);
And all that logic about what is a "published" post, how blog is connected to post, etc., goes into your service method instead of your controller. The other big difference is that service methods should return fully-baked data, i.e. a list type rather than a queryable. The goal with a service is to return exactly what you need, while the goal with a repository is to provide an endpoint to query into.

ASP.NET MVC Business Logic in Domain Model vs Service Layer

I have been reading about where to put business logic in ASP.NET MVC Project for a while and I still can't get clear on some things.
1 - Domain models. What are these really? In my Model folder I have only a bunch of classes corresponding to my database. I am using EF code first. I assume these are my domain models.
2 - Service Layer. This answer suggests a service layer and I think this makes perfect sense. I had decided to go with this one. However, Martin Fowler's "Anemic Domain Models" article messed up my mind.
I am not really sure how can I add logic to my domain models.
I have gone through many business logic-related questions and each of them proposes either 1 or 2. What I don't understand is how I can implement the first one. Adding methods to entity classes (domain models for me) does not make sense at all. And why is the second approach considered bad?
First off, your Model folder in your Asp.Net MVC project should be used for ViewModels. These are the models that your Controllers send to your Views. They should be highly optimized for the View, meaning only the properties needed for the view, and nothing else.
What you are taking about, Domain Models, are the same as Business Models, and belong in your Business Layer. The Model folder in your Asp.Net MVC project are the models for your UI Layer.
The second approach, business logic in your service (really business) layer is not considered bad. It's a very nice buffer between your Data Layer and your UI Layer (3-tier architecture). Your data layer handles getting data, from either web services or a database, and your business/service layer handles translating that data into business/domain models. It also holds any business logic, like calculations, etc.
These business/domain models are usually POCOs, but they don't have to be. This is how I sometimes set up my business models:
public class BusinessObject
{
private DataObject _dataObject;
public BusinessObject(DataObject dataObject)
{
_dataObject = dataObject;
}
public int BusinessId
{
get {return _dataObject.Id;}
set {_dataObject.Id = value;}
}
public string Name
{
get {return _dataObject.Description;}
set {_dataObject.Description = value;}
}
}
I prefer to NOT have business logic in domain models. I keep my domain models usually as POCO's to represent my DB tables/schema.
Keeping the business logic away from the domain models will allow me to reuse my domain model with another project as well.
You may consider a middle layer between your controllers and your data access layer/ Repositary layer to handle this. I would call this as a service layer.
I know this has already been answered, but I categorize models into 3 groups
ViewModels - These are light weight (often poco) classes that model the data needed by a page on your site. These classes handle the mundane boilerplate of what gets shown to the user, and changes when the data that you want to display changes.
DomainModels - These are normally heavy weight business logic classes. They normally model the core business rules for what you're doing. These classes are often highly cohesive and are where the majority of the work that makes your site special happens. I said these models are normally heavyweight but in reality if all your project does is take that data from the user and stick it in the database, this class is going to be a little data mapping class. Many times you'll see these classes being composed of persistence models and returning view models.
PersistenceModels - These are models of your persistence mechanism. For most of us this means modeling a database table, but could also be a complex nosql document or json (or whatever) data that's returned from an api request. Their responsibility is to handle the mundane boiler plate of what shape your external data takes.
Keep in mind also that you don't always need to have all three of these types of models present in your project. Sometimes your view model will be line for line what you're persistence model is. In that case you'd be wasting your clients money to write the whole thing twice and add a domain model to map one to the other. You're the developer and it's your job to know when to build a air-craft carrier to go to the store for groceries.
Domain models should be able to perform their work on their own and expose properties and methods that represent their state and functions. They act as roots (aggregate roots) to a hierarchy of information that is required by models to function. They remain hidden only available to services.
Services expose business/domain functionality to the outside world (web services, UI etc) as a set of APIs following the message pattern (requests/responses), by retrieving models from the repositories that encapsulate the data access layer, then calling methods/business functions on the models and finally saving them back to the repositories.
Some times it feels that services repeat methods of business objects, but in time and real practice that is not what really happens.
In a real domain driven design you need at least 3 sets of objects. Business Objects, Repositories of Business Objects and Services.
Think as if your requirement is always that each type of component is written by different teams. One team requires an exposed service without knowing the details and without the other having to write the logic on the service it self. The service could then be consumed by anyone that requires it without having to dig into the core model itself.
Application flow control logic belongs in a controller.
Data access logic belongs in a repository.
Validation logic belongs in a service layer.
A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer.
The service layer contains business validation logic.
For example, a product service layer has a CreateProduct() method.
The CreateProduct() method calls the ValidateProduct() method to validate a new product before passing the product to the product repository.
Source:
http://www.asp.net/mvc/overview/older-versions-1/models-data/validating-with-a-service-layer-cs

Why do we use ViewModels?

I have recently started working as a web developer. I work with ASP .NET MVC 4 and NHibernate.
At my work-place, we are strictly made to use viewmodels to transfer data to and fro between a controller and a view. And the viewmodels are not supposed to contain any object of a model.
I understand that it is a sort of a tier between the controller and the view.
But I find it repetitive and redundant to write a viewmodel class even if we can directly send the model's object to the view (in most cases).
For example, if i want to display an order i can do this in the controller's action -
return View(Repository.Get<Order>(id));
But instead, I have to write a viewmodel, fill it with the fetched order and then pass it to the view.
So, my question is, what purpose does writing viewmodels serve when we can use the model's object as it is?
For smaller projects, you're right. I hear your argument and sympathise - however there are good reasons for this, drudged and repetitive work, especially in larger and more complicated applications:
It's essential to perform all processing within the Controller's action. However in the example you've given, the Repository.Get method might return a lazily-evaluated IQueryable object, which would mean the DB wouldn't be hit until the View is evaluated. For a variety of reasons this is bad. (A workaround is to call .ToList while still in the controller).
"A view should not contain any non-presentational logic" and "You should not trust the View" (because a View could be user-provided). By providing a Model object (potentially still connected to an active DatabaseContext) a view can make malicious changes to your database.
A View's data-to-display does not always map 1:1 with its Model's data, for example consider a User Details page:
A User's EF Model object represents its entity in the database, so it probably looks like this: User { UserId, UserName, PasswordHash, PasswordSalt, EmailAddress, CreatedDate }, whereas the fields on a "User details" page are going to be User { UserId, UserName, Password, ConfirmYourPassword, EmailAddress }, do you see the difference? Ergo, you cannot use the EF User model as the view model, you have to use a separate class.
The dangers of model manipulation: if you let ASP.NET MVC (or any other framework) do the model binding to the incoming HTTP POST Request then (taking the User details example above), a user could reset anyone's password by faking the UserId property value. ASP.NET will rewrite that value during binding and unless you specifically sanitize it (which will be just as drudgeful as making individual ViewModels anyway) then this vulnerability will remain.
In projects with multiple developers working in a team situation, is is important that everything is consistent. It is not consistent to have some pages using bespoke ViewModels but other pages using EF Models because the team does not share a concious mind, things have to be documented and generally make-sense. For the same reason a single developer can get away without putting excessive XML documentation in his source code, but in a team situation you'll fall apart if you don't.
There is a slight workaround in your case I'll share with you, but please note the preconditions:
Your views can be fully trusted
Your views contain only presentational logic
Your application is largely CRUD
Your views correspond 1:1 with each EF entity model (i.e. no JOINs)
Your views only deal with single Simple models for POST forms, not Complex models (i.e. an object graph)
...then you can do this:
Put all one-way, non-form-related data into your ViewData collection, or the ViewBag in MVC 4 (or even a generic ViewData<T> if you're hardcore). This is useful for storing HTML page titles and sharing data with Master pages.
Use your fully-evaluated and loaded EF models as your View<TModel> models.
But use this approach with caution because it can introduce inconsistency.
Well, i'm starting to think the pragmatic approach to every problem is required and not to just subscribe to the purist architectural standards out there. Your app may be required to run in the wild and be maintained by many developers serving a large set of client etc. and this may direct or drive your architecture.
The ViewModel is essential when you want a separation of concerns between your DomainModel (DataModel) and the rest of your code.
The less dependencies you have between the Model, View and Controller the easier down the line it will be to make changes to the DomainModel without breaking the interface contracts in the View and Controller etc. etc. But once again it's something to be pragmatic. I like the approach as code re-factoring is a big part of system maintenance - refactoring may include a simple spelling mistake on a property of a Model - that change could ripple through the code to the Contract level if the dependencies are not separated; for example.
The ViewModel is used to translate the data between your DomainModel and you Views
A simple example of a datetime stored in Informix has to be translated to a .Net DateTime. The ViewModel is the perfect place to do this translation and does not force you to put translation code in all sorts of unwanted places.
One attribute of a good design [of anything] is the ability to replace or modify a part of the implementation with little or no affects to the rest of the parts of the system. But this takes effort and time to achieve - it's up to you to find that practical balance between a perfect design and a design that is just enough
But yeah, there are many other good reasons to use certain patterns - but the bottom line is this:
Nothing forces you to use ViewModels... ASP.NET MVC won't force you. Take advice from the pragmatist inside you.
If you use same Models as your ViewModels, your application should be very small and simple and should contain only CRUD operations. But if you are building large or enterprise applications with large teams (with two or probably more developers), you should have concepts like Dependency Injection, Services, Repositories, Façades, Units of Work, Data Access Objects etc.
To simplify your mapping needs between Models and ViewModels, you can use AutoMapper
https://github.com/AutoMapper/AutoMapper
or install with nuget
Install-Package AutoMapper
According to me, it is essential to have one more layer(ViewModel) on top of Model layer for complex applications that performs most of the CRUD operations because it has following advantages:
To establish loose coupling between Model and Controller. So that any DataModel related modifications will not be affected to Controller.
If you've implemented your application's ViewModel layer correctly
by providing maximum level of IOC(Inversion of Control) via
DI(dependency Injection using Unity/other frameworks), etc., it will
also help you to MOQ your ViewModels(dependencies) for testing only
the controller's logic.

ASP.NET MVC - is it okay to have sideline presentation logic?

In most documentation you read about ASP.NET MVC, the entire 'Separation of Concerns' is very heavily pushed. Dependency Injection/Inversion of Control, Unit Testing, keeping 'logic' out of the Views, etc.
But how far is this intended to be pushed? Is it bad practice if a specific task requires extra logic beyond the 'three layer' approach of View/Model/Persistence?
For example, I have a solution set up with four individual projects.
Project.Web (ASP.NET MVC) [ References Data.dll, Models.dll ]
Project.Data (Fluent nHibernate Mapping) [ References Models.dll ]
Project.Models (POCO, Helpers, Factories, etc)
Project.Tests (Unit Testing)
Up until now, this has served me pretty well. But I require some very abstract logic for some of my MVC Views, such that I need to take part of the Models and arrange a View Model that is persisted in the database.
This cannot happen in my Data section, as that would dispose the re-usability of it, and there is business logic included in the process. It cannot entirely happen in my Models section, because that would require it to have knowledge of the Data section, which it does not. And I do not want to put it in the Web section because I don't want data access code there.
Question
Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to? Moreover project concerns aside, is this a bad approach in general or is this something a lot of you find yourselves having to do at times? Part of me feels that if I am having to resort to this, then I've just built my software wrong - but at the same time I am very confident I have done a fairly good job, it is just too abstract to make a raw HTML interpretation of without middle-man arrangement.
It's been my experience that single responsibility is a great way to write code you expect to change early and often. Like Jan, I too have a solid line between who does what, when. The more you enforce this, the easier it is to replace an slice of your system. I recently removed linq2sql with EF4.1 and because of SRP, once I got the tests passing around my new EF4 layer, everything else just worked.
That said, I typically let unit testing dictate where these things live -- it's my driver for SRP as well as asking the basic question "must =class/service= know about =something else= to do it's job?" If the answer is no, it goes somewhere else -- if yes, it's a dependency. Now, if it becomes painful, that's its way of telling me "this is stupid" (see this question for the stupid) and I've attempted to force something instead of allowing it to fit the way it must.
Onto your core queston : you've clearly identified a gap in your code -- it MUST know about two things (data and model) and I agree, it should be its own thing and pulled out. I would call this a "DomainService" or maybe just DTO, but presentation feels like it would be doing more than just prepping data. (I'd argue the view handles the presentation ... maybe you simlpy mean presenter?). I would also argue against your perception that you did "something wrong" - no, you're learning to write code differently and allowing it to evolving, EXACTLY as it should. :-)
I use the following structure, which more or less solves all problems we've had regarding MVC structures.
Models: contains all ViewModels. Just clean, only getters and setters.
Business logic implementation: Set of projects that contains database logic, DAL entities etc. But only has one interface (in our case this is a WCF API).
ServiceLayer: the bridge between Business Logic and ViewModels. Doesn't know anything about web.
Mapping layer: translation between business entities and ViewModels.
Web project: holds very thin Controllers and Views, and everything web related.
A web page flow will follow this flow:
URL maps to a certain Action
Actions are really clean, they only reference a method in the ServiceLayer
The ServiceLayer executes one or more actions in the Business Logic Implementation (get data, store data, etc.)
The ServiceLayer passes the business entities to the Mapping Layer.
The Mapping Layer translates business entities into ViewModels
In code this would look like:
// action
public ActionResult ListOfObjects () {
var model = new ServiceLayer.ObjectsClient().GetListOfObjects();
return View(model);
}
// Service Layer
public ListOfObjectsModel GetListOfObjects () {
var businessEntities = BusinessDao.GetThingysFromDb();
var model = Mapper.TranslateToViewModel(businessEntities);
return model;
}
// Mapping Layer
public ListOfObjectsModel TranslateToViewModel(List<BusinessEntity> entities) {
// do mapping
}
When handling POSTs you will follow the same flow, but the mapping layer should translate your ViewModel into Data Entities that are given to the Business Logic.
"take part of the Models and arrange a View Model that is persisted in the database"
Then its not a viewmodel.
Does that simplify things?
What is a 'ViewModel':
More than often 'ViewModel' is confused with persistence. If you look at the word more closely it is a combination of 'View' + 'Model' - which essentially means it is a single unit of data that is required to fulfill all the needs of your view. A ViewModel can infer multiple entities or sources to build what is required by the View.
Now Coming to your question:
Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to?
Re: If I had to do it, I would have created a seperate namespace (folder) in my MVC project named 'ViewModels' and placed all my Viewmodels in there. In my opinion if you want your ViewModels to be in a separate namespace, it would not actually violate MVC. You are just incresing the separation or making it more unit test friendly.
Just my 2 cents!!!

Accessing domain objects in the view

If I don't want to expose the internal state of my Domain Objects, but I need to display them, I can think of three approaches.
Which of these is the most "correct" (if any?).
The "DTO/ViewModel approach".
This seems to be a popular approach
in the ASP.NET MVC world (especially
with the use of AutoMapper).
The
"decorator approach". If I have a
"Customer" entity, I decorate it
with a "DisplayableCustomer" who can
access the internal state of the
customer (in most languages that
I've dealt with).
The "interface
approach". Where I do something like
this:
class Customer {
....
public void renderWith(CustomerRenderer renderer) {
renderer.renderCustomer(address,name);
}
}
interface CustomerRenderer {
public void renderCustomer(Address address, Name name);
}
I vote for, and widely use, your #1 option. Several reasons why:
Allows for complex view models, like combining multiple lists of my domain objects. Think a PostViewModel with a Post element and an IList container hanging off of it.
On my current project, we have abstracted the domain validation to where it bubbles up into our custom ViewModels, and do some slick Ajax-validation on forms.
While the concept doesn't directly expose your domain objects on the Model, I have no problem hanging Post off of a property of my PostViewModel.
The last point is why the ViewModels concept really exists. It's no violation of DDD to expose your Domain object all the way up to your UI or even the view - this is by designed and expected of DDD and UI concepts. You only expose objects from your domain to use, and lock in/persist their states with services and infrastructure. So, you are in no violation of using the actual Domain object in your UI.
It's when you involve MVC concepts for your UI, and trying to render that specific View of a page/location. You may (and will) have additional display elements that may not be related to the Domain at all, like a Progress Bar that is only for the UI. A progress bar is a concern only for the UI and APplication layer. It has nothing to do with your domain.
So, the DDD solution I accept is to use a hybird object in the Application/UI layers that can hold a number of objects: both Domain objects and Application objects to render for that one specific View. This is the concept of a ViewModel, at its core reason of being.
The ViewModel concept can be thought of as your Application Layer non-business objects in DDD terms.
Going off topic a little and talking about one specific technology, ASP.NET MVC has additional features to help make this concept work together nicely. It's not directly built into ASP.NET MVC, but is available as an additional assembly from Microsoft called the Futures project.
Check out my blog post about a couple of features, the single most useful feature is the RenderAction extension method:
http://eduncan911.com/blog/html-renderaction-for-asp-net-mvc-1-0.aspx
This is an extremely powerful concept that spins up the underlying controller and calls the action method. Doing this greatly simplified our ViewModels to only care about the View they are rendering. I no longer have to attach things like sidebar controls or other common data boxes, navbars, etc that have nothing to do with the View.
RenderAction is different then RenderPartial for pure DDD reasons: It lets you move the business logic back into a Controller, where it belongs. And the controller calls the proper view to render it's display. This strictly follows both DDD and MVC concepts.
Microsoft has stated that RenderAction will be part of ASP.NET MVC 2.0 when it is released next year.
Sorry for the rant...

Resources