views:

298

answers:

3

Say you have an ASP.NET MVC project and are using a service layer, such as in this contact manager tutorial on the asp.net site: http://www.asp.net/mvc/tutorials/iteration-4-make-the-application-loosely-coupled-cs

If you have viewmodels for your views, is the service layer the appropriate place to provide each viewmodel? For instance, in the service layer code sample there is a method

    public IEnumerable<Contact> ListContacts()
    {
        return _repository.ListContacts();
    }

If instead you wanted a IEnumerable, should it go in the service layer, or is there somewhere else that is the "correct" place?

Perhaps more appropriately, if you have a separate viewmodel for each view associated with ContactController, should ContactManagerService have a separate method to return each viewmodel? If the service layer is not the proper place, where should viewmodel objects be initialized for use by the controller?

A: 

I suppose that depends on what you consider the "services" to be. I've never really liked the term service in the context of a single class; it's incredibly vague and doesn't tell you much about the actual purpose of the class.

If the "service layer" is a physical layer, such as a web service, then absolutely not; services in an SOA context should expose domain/business operations, not data and not presentation logic. But if service is just being used as an abstract concept for a further level of encapsulation, I don't see any problem with using it the way you desribe.

Just don't mix concepts. If your service deals with view models then it should be a presentation service and be layered over top of the actual Model, never directly touching the database or any business logic.

Aaronaught
In the sample, the "service layer" is an abstraction between the controller and a repository layer whose stated intent is to be used for validation before passing data to the repository. It also contains the ListContacts() method above as well as a GetContact() method to get a single Contact object which are used by the controller for binding views. So it sounds like it seems appropriate for said service layer to know about the list of viewmodels that might be needed by a fully fleshed out controller, correct?
erg39
@erg39: If your service is doing validation then it's fundamentally part of the model. It does not handle presentation logic and should not be coupled with view models.
Aaronaught
@Aaronaught: Where would you say the appropriate place to initialize viewmodels would be? Should it just be a separate abstraction, like a "viewmodel service layer"?
erg39
@erg39: It's normally part of the controller logic. If the logic is very complex then it's usually delegated to a mapping layer (or AutoMapper).
Aaronaught
There's little value in describing a software layer as physically separate. A layer separated via SOAP method calls to a Web Service versus the same memory space is irrelevant, and is an architectural detail. While it may affect the topology of the layer, it shouldn't affect the logical separation.
Robert Paulson
@Robert: I don't know how you can possibly say that. Physically-separated components do not behave the same way as logically-separated components. Latency is different. Error conditions are different. Asynchronous operations are *completely* different. You can't perform lazy-loading over a web service. The *architecture* of a system comes *before* the code and affects how the code must be written, it is not some afterthought or trivial "detail".
Aaronaught
OP didn't appear to understand what a service (layer) was, and your answer wasn't particularly helpful in that regard. What I said was that _implementation concerns shouldn't affect the (logical) separation of software layers_. Flavour of architecture _certainly_ affects the code, but I never said architecture wasn't important, so please don't put words in my mouth. Good day.
Robert Paulson
+4  A: 

No, I don't think so. Services should care only about the problem domain, not the view that renders results. Return values should be expressed in terms of domain objects, not views.

duffymo
+1  A: 

Generally, no.

View models are intended to provide information to and from views and should be specific to the application, as opposed to the general domain. Controllers should orchestrate interaction with repositories, services (I am making some assumptions of the definition of service here), etc and handle building and validating view models, and also contain the logic of determining views to render.

By leaking view models into a "service" layer, you are blurring your layers and now have possible application and presentation specific mixed in with what should focused with domain-level responsibilities.

CaptainTom
@Captain Tom: In the example, the controller's Index() method builds the view it returns from ListContacts() method shown above, which returns an IEnumberable<Contact>, so isn't the viewmodel already leaking into the "service layer"? Is this a poor example? And if so, where is the appropriate place to initialize viewmodels for consumption by the controller's various views?
erg39
@erg39: Isn't Contact a domain model type? If so, then no. You may have something looks like a Contact for your view model but may also have additional information specific to a single view or set of views. Contact doesn't (or shouldn't) know anything about any particular details for a view.
CaptainTom
@erg39: As far as initializing view models, the controller has the responsibility of building new view models instances and validating/validating view models received from the view.
CaptainTom
Thanks everybody, very helpful
erg39