Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm working on a MVC4 N-tier application and have a quick question about Service to Controller relation and using Domain/ViewModel.

   public ActionResult Details(int id = 0)
    {
        TenantDomainModel tenant = _tenantService.GetById(id);
        TenantViewModel tenantViewModel = Mapper.Map<TenantViewModel>(tenant);
        return View(tenantViewModel);
    }

As you can see my service return a DomainModel that my controller use to create a ViewModel using Automapper.

Is there a better way to do that ? Ideally I would like to have no domain model referenced in my Presentation/Web layer but i'm not what are the exact best practice on this specific point.

Thanks

share|improve this question
add comment

3 Answers

The answer is... it depends on what you're intending. If you're looking to achieve scalable code then the best practice is generally to create a Domain Transfer Object (DTO) that is a view into the current state. This is done in the services themselves usually and are regenerated every time the domain object changes (Eventual consistency is key, as trying to keep consistency at all times won't happen). The DTO is optimized for the query that it serves as well as the data it is intended to display, it may be a composite of more than one domain object. But most importantly it is independent of the domain object and is unaware of the domain object. That might sound contradictory, but it's not. I would highly suggest reading up on Command Query Response Segregation (CQRS) as it is probably the best approach to what you're doing.

CQRS allows you to make your web site (or any client) agnostic to your domain. This is important as your domain model needs to manage its own business rules internally and should not rely on an external consumer to ensure consistency and correctness. As far as the website is concerned the domain to it is the DTOs that are designed specifically for its queries. When you need your website to be able to change your domain you expose commands that it sends to the services with the domain entity id and the relevant data just for that command. The services then execute the command or return a result saying that they were unable to.

Now the fully qualified answer here must come with the caveat of: if this is an internal only low usage application you need to decide whether having a scalable domain/query model matters more than speed of completion. Do you need the system fast, or do you need the system to be fast and scalable.

share|improve this answer
    
Excellent thanks , my primary goal is scalability for future supports. It's not meant to be used by hundred thousands of users ( most likely around 1k max ). So i'm trying to find a good balance between scalability and complexity. I will look at CQRS and DTOS it's look to achieve exactly what I was looking for. –  Pxl Apr 7 '13 at 19:59
add comment

One good way to keep these concerns out of your service models is to create extension methods in the web project to handle the mapping tasks. Also makes them much more easily testable in isolation.

share|improve this answer
add comment

I just spent some time using DTO between the Controller/Service layer it was fairly easy and pretty efficient ( especially with Automapper ).

Now I have another question regarding the usage of DTO between Service > Date layer. I'm using a UOW pattern with generic repositories that return POCOs. Is there any best pratices here ? I realize that basically my data layer bleed on the business layer.

I can see that ideally my repository can return DTOS to have a perfect separation between layers but i'm looking at a practical example. I just wonder I can keep a generic repository approach that return DTOs.

Thanks for the help !

share|improve this answer
    
Create a new question. You've added this as an answer to an existing question. –  Simon Whitehead May 8 '13 at 3:43
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.