What I have done in this scenario is created a helper class (currently it is
in the same project as controller) to produce necessary data for the
dropdown. Idea is to separate this and place it in the middle of Repository
and Controller (may be service layer where it belongs). Initially I had this
function return IList, I have changed it to return SelectedItems. IMO
dropdown is a very generic routine specific for Web, this can easily be
generalized into one helper method by passing respective model and fields...
I am guessing this can be done easily.
Why? Repositories return the correct elements and if you're reusing them in
your mvc app, there's already some helpers for generating dropdown items.
Using services as facades is a good idea, but lets not get fired up with it
and start adding them all over the place...
Luis
This generalization could be dangerous. In my opinion, repositories give you
access to aggregates. Is there anything out there that says that an
aggregate is the same thing as an entity?
2. You have your controller talking directly with your repo. There is no
buffer between your presentation and your data, this leaves really no place
for any kind of business logic. Why not use a service layer to buffer? You
can use this layer to implement your business rules as well as to serve up
DTOs the controller can use for presentation.
Yes, you could have this service layer, but if you're not using DTOs (which
is ok in simple scenarios), then you're just adding unnecessary layers
here..
I would suggest having the repository return either an IList<Vendor> or
List<Vendor> rather than SelectedItems. By doing so, you can leave it up to
the service layer to return a presentation specific DTO or type. This allows
you to switch
Why do people keep returning IList<T> collections instead of IEnumerable<T>?
Are you going to add items to the returned instance of your collection? I
guess not and in most collections this should be a readonly scenario. Why
not force this by returning IEnumerable? I've been using them for a long
time and haven't really needed ILists in 99% of the apps I've developed in
the last months.
Example
My application displays information to users via a web project using MVC as
well as implements a reseller API via WCF. The web site makes calls via the
controllers to the service layer, which returns DTOs that are specific to
the calls. The views can call into the controllers via jQuerys AJAX API to
update parts of a page. On the other side, the WCF web service calls into
the service layer to get WCF specific DTOs that in turn are sent to the
requesting caller. In the case of the WCF DTOs, they could be XML documents
or JSON objects or ??? With regards to the web site, the returns from the
service layer will most likely be traditional DTO class objects.
Hum...why aren't you reusing the WCF layer in your web app? This would let
you have your domain on a single place.
Luis
Since you're guessing the future :), then I'll say that there really isn't
any other way as having different contexts for writing and for querying.
Your examples are about querying existing data, right???
Luis
I guess we're talking about services that coordinate work on the domain,
right?
A simple rule of thumb I would use in determining whether to use a repo
specific service over a composite service would be the number of
repositories the controller would need to access to get the job done. If the
answer is 1, then accessing the repo or a repo specific service would be the
way to go. If more than one, I would then introduce a controller specific
service that can take care of all the repository interactions amongst the
various repos, then serve me up a nice DTO I can use.
Not sure if this is a good rule. There might be several scenarios where
having a service is a must even though you only have a repository.
Luis

I'm not sure if that is the case. For instance, I see domain services as
something which exists to expose an operation which really doesn't belong
to any entity or value object of the current domain. A completely different
role from applications services, which I see as being there for coordinating
work and simplifying use of the domain elements by clients.
This is why it is a rule of thumb it is not meant to be the law, rather a
simple measure. It really is up to the developer to decide to follow this or
to not follow it. If there is a case where even with a single repository you
need a service, then that should override that case and the developer should
implement a service layer.
Ok, but what I don't understand is why having several repositories is enough
for leading to the creation of a(n) (application) service...
Luis
My generalization is based upon NOT knowing what the domain model looks like
and going with the repositories following SRP. IMHO, repositories do not
return aggregates, to me that would be something more along the line of
business rules like reporting. I think an example of what you think an
aggregate return would look like based on a domain model would be helpful.
To me, an aggregate is a cluster of associated objects that we treat as one
for updating scenarios. Each aggregate has a root which is the only point of
entry to the aggregate. The root is always an entity and you should only
hold references to this element outside the aggregate. The root entity
defines the identity of the aggregate, though you can have internal
identities, which are local to that aggregate. Another important thing you
get with aggregates is consistency. You should always ensure that aggregates
are consistent with their rules. One important thing to keep in mind is that
you might have other entities inside an aggregate, though, as I've said,
those items are only important inside that aggregate. There might also be
aggregates composed of only one entity, though they're rare (especially in
complex domains). Main point here is that when you've got an aggregate, you
load them and save them as a group (ie, even though you might have several
entities, when you have aggregates you should work with the aggregate as the
base unit and not against entities). I guess that this resumes my point of
view on aggregates. To ensure consistency, you should, of course, follow
several principles. One of them says that you should only return a reference
to the top root element. Getting inner entities is ok too if you get them
through the top root entity and if you're only using them on a single
operation.
With aggregates, your repositories must return references to them and not to
single entities...
Once again, nothing more than another OPTION. Ultimately it is up to each of
us as developers to decide whether the application warrants a services layer
or not. For me, I always use one, if more nothing more than enforcing the
business rules for the application. It's a personal preference and nothing
more than that.
The only thing I'm not following here is why using services will enforce
business rules. Business rules should be enforced by your domain objects.
Are you saying that your domains are only usable through your services? If
that is the case, then I disagree with that approach since I see these
application services as coordinators only. What do I mean by this? Simply
that the clients of my domain assemblies can bypass my application services
if they want, but they cannot skip any of the domain rules validation
because they're not using the application services I've provided.
To be quite honest I have no idea why I always use IList<T> or List<T> for
returning when it is going to bind to a drop down or data item. I guess that
one is nothing more than a habit for me.
Yes, but besides that (habituat), is there really any good reason for doing
that? I really prefer to limit my return
I am not sure what you mean by having my domain in a single place. The WCF
layer might not need to be as robust or return all of the data a web
application would. Take my example and then modify it to say I need a web
front end for my customers and a WCF for my resellers. The reseller WCF
service would not need all of the functionality that the web would, so why
would I burden it with all that the web needs? I this case if I follow the
logic you applied to having service layers, would it not just add additional
complexity where it might not be needed?
Ok, that is a valid point, but I'd say that in that case you have different
contexts for each app. What I was trying to say was that if you're reusing
the same domain (and context) then you could probably configure all access
to your domain through the WCF. Doing that would mean that you could return
DTOs and add other domain orthogonal aspects like logging, authorization,
etc...
Luis