Design philosophy advice for handling multiple entity use in controllers

6 views
Skip to first unread message

todd brooks

unread,
Feb 17, 2009, 4:05:11 PM2/17/09
to S#arp Architecture
I have a, what I think to be common occurrence, in my project where a
single controller needs access to multiple objects. Think of a
Product controller. On the view for creating a new Product, the user
will need access to all the vendors (for a simple drop down to choose
from); same goes for other objects, such as categories, et al.

What I came up with, I would like to hear criticism for or against,
because I have not seen any discussion of this...or very little.

In the IProductRepository.cs, I've added an additional signature for
retrieving a list of Vendors:
List<Vendor> GetAllVendors();
Now, for the sake of discussion, this is simply returning a full list
of those entities. This isn't strictly necessary, as I could have
created a separate VendorDTO class that would only return the
necessary properties (Id and Description) required for a drop down.
Thoughts on that?

In the implentation class, ProductRepository.cs, I stub it out as
follows:
public List<Vendor> GetAllVendors()
{
return new Repository<Vendor>().GetAll();
}

In the Create view of the ProductsController.cs, I create an object to
dump the vendor list to:
public ViewResult Create()
{
ViewData["ProdVendors"] = productRepository.GetAllVendors();
...
return View();
}

and then use it in the actual page to populate a dropdown using the
HTML helper:
<%= Html.DropDownList("VendorDropdown", new SelectList((IEnumerable)
ViewData["ProdVendors", "Id", "Description")) %>


Is this the acceptable way of handling this? Am I making this more
complex than it needs to be? It seems to work well, and the only perf
optimization I have done is to use a DTO class to shrink the amount of
data being transferred.

Jamir Shaikh

unread,
Feb 17, 2009, 10:49:06 PM2/17/09
to sharp-arc...@googlegroups.com
Todd,

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.

I don't necessary like ProductRepository to get allVendors, unless otherwise you are looking AllVendors for a Product... This would create some amount of unnecessary coupling.

Thanks,
Jamir

Alec Whittington

unread,
Feb 18, 2009, 12:34:11 AM2/18/09
to sharp-arc...@googlegroups.com
Todd,
     A couple of things stand out to me with your solution. 
  1. You have your Products repository returning Vendors. Not knowing what your domain model looks like, I am going to assume you have a Vendor entity (please correct me if I am wrong) as well as a Product entity. With that setup, each should have it's own repository. As such, a call to the Vendor repo should be made to retrieve your list of vendors.

  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.
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 presentation layers easily as well as allowing you to have multiple presentations. For the record, my own opinion on presentation layers means not just web or desktop, but wcf as well. These 3 can tie into the service layer to get their presentation specific return.

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.

If you are using interfaces for your repositories to implement, you would use Windsor ( or the IoC  of your choice) to inject the proper repository implementation into your service layers. This loosely couples the Service Layer from the Data Layer. You would do the same thing with your Service Layer, have each service implement an interface. Then the controller uses Dependency Injection like the Service Layer did to inject the proper service. Remember DI is your friend, it will help you loosely couple your layers.

If any parts are unclear, please feel free to ask questions. Also, this is my own opinion, not that of the project or any specific person other than myself.
Cheers,
Alec Whittington

todd brooks

unread,
Feb 18, 2009, 1:45:34 AM2/18/09
to S#arp Architecture
Thank you for your comments.

I am interested in seeing a fleshed out service layer integrated with
S#arp. I believe Neo has created a post regarding this which I'm
reading now:
http://nicecode.wordpress.com/2009/02/17/introducing-sharparchitecture-service-layer/

I'm curious about your statement in #2, though. "You have your
controller talking directly with your repo". This is the default
behavior and implementation in S#harp. Are you saying that this is
now how it should be done in your opinion? If so, do you have an
example of your service layer implementation?

Regards and again, thanks for both of your comments.

todd

On Feb 17, 11:34 pm, Alec Whittington <alec.whitting...@gmail.com>
wrote:
> Todd,     A couple of things stand out to me with your solution.
>
>    1. You have your Products repository returning Vendors. Not knowing what
>    your domain model looks like, I am going to assume you have a Vendor entity
>    (please correct me if I am wrong) as well as a Product entity. With that
>    setup, each should have it's own repository. As such, a call to the Vendor
>    repo should be made to retrieve your list of vendors.
>
>    2. You have your controller talking directly with your repo. There is no

Jamir Shaikh

unread,
Feb 18, 2009, 2:36:03 AM2/18/09
to sharp-arc...@googlegroups.com
My assumption when working with dropdowns is that this will be using default S#arp Repo.

Initially I had a routine (did not want to make my controller become too messy), which converted the IList from default repo to Dictionary of Key and Value pair and back to IList to send it back to ViewState.

Issue I had was, when I wanted to pass additional attributes to my MVCContrib Dropdown helper, it did not take Selected value (no overload worked). One suggestion I got that, we need to create a SelectedItems and set the Selected = TRUE priot to passing it to View.

Here are some of the code

My routine, which returns Selected List

        public IEnumerable<SelectListItem> GetList(int iSelectedValue) {
            IRepository<ExpenseType> repository = new Repository<ExpenseType>();
            List<ExpenseType> lists = repository.GetAll();

            var selectedItems = (from types in lists
              select new SelectListItem {
                  Text = types.ShortDesc,
                  Value = types.ID.ToString(),
                  Selected = (iSelectedValue == types.ID)
              });
            return selectedItems;
        }

In my View

<%= Html.DropDownList("ExpenseTypeID", (IEnumerable < SelectListItem >)ViewData["ExpenseTypes"])%>

This works for me. This is just my first pass. I would want to see if I can generalize this routine to be used from any Model.

Thanks,
Jamir

cathal

unread,
Feb 18, 2009, 6:18:41 AM2/18/09
to S#arp Architecture
Hey Todd,
Just to pick up on a question you asked Alec:

>>I'm curious about your statement in #2, though. "You have your
>>controller talking directly with your repo". This is the default
>>behavior and implementation in S#harp. Are you saying that this is
>>now how it should be done in your opinion? If so, do you have an
>>example of your service layer implementation?

Yes the controllers talk directly to the repository, by via an
interface. The concrete object is injected into the controller on
instantiation. This is important as it allows us to mock the
repository for testing. This is the point that Alec is trying to
stress by saying that "dependency injection is your friend" - whether
this be with the use of a service layer or otherwise.

One suggestion I'd make is to achieve this with a SubController. I
posted on this recently i.e. I've been playing around with them and
think they're cool. I guess it's important to know that they don't fit
all scenario's, but what do people think of the following suggestion??

You have a subcontroller called AllVendorsSubController (or if you
need to give it context it could be e.g.
VendorsByCountrySubController). And you have a partial view
(AllVendors.ascx) that is simply the vendor drop-down expecting a
model from the subcontroller of type IList<Vendor>.
This subcontroller needs to have the IRepository<Vendor> injected into
it, and you can chain this subcontroller with any controller that
requires it - so ProductController in your case, but chain it with any
other controllers that need this same functionality.

Cathal.



On Feb 18, 6:45 am, todd brooks <brooks.t...@gmail.com> wrote:
> Thank you for your comments.
>
> I am interested in seeing a fleshed out service layer integrated with
> S#arp.  I believe Neo has created a post regarding this which I'm
> reading now:http://nicecode.wordpress.com/2009/02/17/introducing-sharparchitectur...

Zihotki

unread,
Feb 19, 2009, 8:59:27 AM2/19/09
to S#arp Architecture
Hi Jamir,

Try not to use ViewData directly. This is a bad practice (I mean magic
strings and numbers and so on). In order to transfer multiple values
from controller to the view you should use some DTO:

public class SomeViewData
{
public IEnumerable<Foo> FooItems {get;set;}
public Bar ActiveBar {get; set;}
public IEnumerable<Bar> ChildBars {get; set;}
}

And in the typed view (e.g. inherited from View<SomeViewData>) you'll
easily know what data is available here. And it's better to use
extension methods to convert some collections of objects in your
viewdata to IEnumerable<SelectListItem>, example:

public static class ViewDataExtensions
{
public static IEnumerable<SelectListItem> ToSelectListItems<T,
ValueType>(this IEnumerable<T> items, Func<T, string> nameSelector,
Func<T, ValueType> valueSelector, IEnumerable<ValueType>
selectedItems)
{
foreach (var item in items)
{
var value = valueSelector(item);
var selectListItem = new SelectListItem
{
Text = nameSelector
(item),
Value = value.ToString(),
Selected =
selectedItems.Contains(value)
};
yield return selectListItem;
}
}
}

usage:
<%= Html.DropDownList("SomeDD",
someViewData.FooItems.ToSelectListItems(x => x.Name, x => x.Id, new []
{1,2,3})) %>

This extension will help you not to write conversions of collections
to IEnumerable<SelectListItem> each time when you need. Hope this will
help you to write better code :)
PS, I think I need to send this extension to MvcContrib guys, it will
be very helpful.

Hope this helps,
Best regards,
zihotki

Neo

unread,
Feb 19, 2009, 9:43:20 AM2/19/09
to S#arp Architecture
@Todd

By default I mean the implementation that comes with Northwind.

> Are you saying that this is
> now how it should be done in your opinion? If so, do you have an
> example of your service layer implementation?

No, I'm saying we should have a service layer between the Controller
and Repository,
exactly like Alec suggested, decoupling with IoC. If you have any
other doubt about my post, fell
free to ask.

On Feb 18, 3:45 am, todd brooks <brooks.t...@gmail.com> wrote:
> Thank you for your comments.
>
> I am interested in seeing a fleshed out service layer integrated with
> S#arp.  I believe Neo has created a post regarding this which I'm
> reading now:http://nicecode.wordpress.com/2009/02/17/introducing-sharparchitectur...

cathal

unread,
Feb 19, 2009, 10:06:48 AM2/19/09
to S#arp Architecture
Hi Zihotki,
Could you give an example of how a single controller might populate
this DTO.
I.e. how does the controller that gets instantiated with
IRepository<Foo> populate the ChildBars collection with a list of
<Bar> items?

Jamir Shaikh

unread,
Feb 19, 2009, 10:37:13 AM2/19/09
to sharp-arc...@googlegroups.com
Zihotki,

This is certainly one step forward. I am still missing the pieces to put together from controller how to get the data back from REPO and call this function to make it happen. How are you doing that in your example?

Thanks,
Jamir

todd brooks

unread,
Feb 19, 2009, 6:18:23 PM2/19/09
to S#arp Architecture
Cathal,

Sorry I'm being thick headed, but can you elaborate on how you inject
the IRepository<Vendor> into the Prorduct controller? I think that is
the obvious piece that I'm not understanding. A concrete example
would be super cool :)

many thanks in advance.

todd

todd brooks

unread,
Feb 19, 2009, 11:43:30 PM2/19/09
to S#arp Architecture
Let me rephrase my question. Is it all just a matter of passing the
necessary repositories into the controller constructor? Nothing else?

todd

Alec Whittington

unread,
Feb 20, 2009, 1:08:08 AM2/20/09
to sharp-arc...@googlegroups.com
Todd,
    you would have something like this:

public class MyController : Controller
{
    private IUserRepo _IUserRepo;

    public MyController(IUserRepo userRepo)
    {
        _IuserRepo = userRepo;
    }
}

With Windsor wired up properly, it will inject the proper concrete instance of the IUserRepo. You would then just work with it like normal.

Hope this helps.
Cheers,
Alec Whittington

cathal

unread,
Feb 20, 2009, 4:51:36 AM2/20/09
to S#arp Architecture
Hey,
I jumped the gun a bit in some of my previous posts.
I read a few posts on "what should I do if my controller/view has a
dependency on multiple repositories?"
I assumed from this that the following wasn't possible:

public class StatusController : Controller {
public StatusController(IRepository<Status> statusRepository,
IRepository<Category> categoryRepository) {
Check.Require(statusRepository != null, "statusRepository may not
be null");
Check.Require(categoryRepository != null, "categoryRepository may
not be null");

this.statusRepository = statusRepository;
this.categoryRepository = categoryRepository;
}

But this of course works fine, and the injection of the repositories
is straight out of the S#arpArch-Box, so I fail to see the problem
here.
Obviously I completely understand that it is not advisable to have
controllers/views with dependencies on many repo objects, and writing
lists of objects to "magic keys in the view data".


On Feb 20, 6:08 am, Alec Whittington <alec.whitting...@gmail.com>
wrote:
> Todd,    you would have something like this:
>
> public class MyController : Controller
> {
>     private IUserRepo _IUserRepo;
>
>     public MyController(IUserRepo userRepo)
>     {
>         _IuserRepo = userRepo;
>     }
>
> }
>
> With Windsor wired up properly, it will inject the proper concrete instance
> of the IUserRepo. You would then just work with it like normal.
>
> Hope this helps.
> Cheers,
> Alec Whittington
>

Billy

unread,
Feb 20, 2009, 8:56:39 AM2/20/09
to S#arp Architecture
There are quite a few ideas being passed around here, so I'd like to
set the record straight on what I feel is the best way to do this.

There are two controller scenarios which need to be addressed: a
simple one and a complex one. ;)

When I say "simple," I mean to imply a controller which is doing very
little coordination other than basic CRUD which might require a couple
of data driven drop downs. In this scenario, I personally do not see
the need to introduce an intermediary service object and related DTOs
and would encourage you to communicate directly with the repository
interfaces. Others may disagree, but I have never seen the benefit of
adding additional complexity to such a simple controller interaction.
Keep it simple when the need itself is simple. Here is an example
controller (I'm winging this code, so there might be a couple of minor
syntax problems):

public class ProductsController {
public ProductsController(IRepository<Product> productRepository,
IRepository<Vendor> vendorRepository) {
Check.Require(... that both are not null ...);

this.productRepository = productRepository;
this.vendorRepository = vendorRepository;
}

[Transaction]
public void Create() {
FormViewData formViewData = GetFormViewData();
return View(formViewData);
}

public class FormViewData {
// The Product property would be set within the Edit(int it)
method
// for setting the form fields to the existing product;
otherwise, it
// would be left as null
public Product Product { get; internal set; }
// This will be used by the dropdownlist to show available
vendors
// to choose from
public IList<Vendor> Vendors { get; internal set; }
}

private FormViewData GetFormViewData() {
FormViewData formViewData = new FormViewData();
formViewData.Vendors = vendorRepository.GetAll();
return formViewData;
}
}

And then in your view...

<li>
<label class="desc" for="product.Vendor">Vendor</label>
<span>
<%= Html.DropDownList("-- Select Vendor --", "product.Vendor",
new SelectList(ViewData.Model.Vendors, "Id", "Name",
(ViewData.Model.Product != null &&
ViewData.Model.Product.Vendor != null)
? ViewData.Model.Product.Vendor.Id
: 0))%>
<label for="product.Vendor">
<%= Html.ValidationMessage("Product.Vendor")%>
</label>
</span>
</li>

Simple, yes? For basic stuff like this, just keep it simple and don't
add any more complexity than is needed.

So that was the "simple" scenario. I regularly have many "simple"
controllers which accept two or three repositories to do exactly what
the above example does.

If you have a more complicated need, if you're controller is starting
to get quite busy (a subjective term I know), or if you have a team
agreement that a service-layer and DTOs are always used as an
intermediary, at that time it would be good to introduce a service
object to act as a middleman between the controller and the
repositories to pull the needed information together. (I honestly
haven't gotten a chance to look at the example service layer that Neo
proposed, but I'm certainly looking forward to doing so. I'm also
putting a couple of blog posts together about service layer approaches
as well.)

But for the simple CRUD forms, it doesn't get much simpler and cleaner
than the example I've provided above.

Billy McCafferty

Zihotki

unread,
Feb 20, 2009, 10:32:10 AM2/20/09
to S#arp Architecture
@cathal
I thought that you was asking about populating DTO from subcontrollers
and I was looking for a solution for this :). But the question was
much simpler.

@Jamir Shaikh
If you not use subcontrollers all is clear, just select necessary data
and populate a DTO with it. I didn't touched subcontrollers yet (just
read about them and looked at examples) so I have no good solution at
the moment.

By the word, extension for DropDownList is in MvcContrib now.

Kyle Baley

unread,
Feb 20, 2009, 10:38:07 AM2/20/09
to sharp-arc...@googlegroups.com
I dunno, it's rare in my experience that any page stays simple for long. In which case, I find it easier to start from a service object always and return a DTO always. These can be simple pass-throughs but when things get more complex, you can add to them without breaking dependencies. Even in simple CRUD scenarios, consider a product edit view. At first, you need a product repository and nothing else. Then the customer wants to select the categories from a drop-down. Then he wants to see the quantity on hand, then a breakdown of this by region. All the while, you're adding repositories to your controller whereas if you started with a service (and it's a presentation-specific service, not a domain service) that calls GetCustomerEditData, you don't need to change the controller from its original form.

This is a bit hypocritical considering I like YAGNI but it's borne from experience, meager as it is.

Billy

unread,
Feb 20, 2009, 11:00:29 AM2/20/09
to S#arp Architecture
It's certainly a tricky balance between judicious planning and
YAGNI. ;) I'd still lean towards extreme simplicity for the
controllers you know are going to remain simple (some of the basic
admin controllers). But for the-next-step up from having the
controllers pull together their own ViewData DTO from the
repositories, I do like your idea of extracting
GetCustomerFormViewData into a service class which could be passed to
the controller instead of the additional repositories.

Billy


On Feb 20, 8:38 am, Kyle Baley <k...@baley.org> wrote:
> I dunno, it's rare in my experience that any page stays simple for long. In
> which case, I find it easier to start from a service object always and
> return a DTO always. These can be simple pass-throughs but when things get
> more complex, you can add to them without breaking dependencies. Even in
> simple CRUD scenarios, consider a product edit view. At first, you need a
> product repository and nothing else. Then the customer wants to select the
> categories from a drop-down. Then he wants to see the quantity on hand, then
> a breakdown of this by region. All the while, you're adding repositories to
> your controller whereas if you started with a service (and it's a
> presentation-specific service, not a domain service) that calls
> GetCustomerEditData, you don't need to change the controller from its
> original form.
>
> This is a bit hypocritical considering I like YAGNI but it's borne from
> experience, meager as it is.
>
> ...
>
> read more »

Alec Whittington

unread,
Feb 20, 2009, 1:07:19 PM2/20/09
to sharp-arc...@googlegroups.com
I agree with Kyle on this one, for the most part. I also am not a believer of allowing my controller to have direct access to my repository. I really like having that service layer there for not only implementing my business logic, but to also serve up DTOs to my controllers, which then sends them to the views. Does this add a layer of complexity where there should not be one, perhaps in some cases. It has been my experience that "simple" views for me are few and far in between. Is it the right way to do things, debatable at best since it really is subjective to ones personal tastes.

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.

What all this really boils down to is a how-to on "Injecting" a Dependency into a controller. You've now got plenty of examples of this so you should be set.

Cheers,
Alec Whittington

Billy

unread,
Feb 20, 2009, 2:13:33 PM2/20/09
to S#arp Architecture
That sounds like a very good rule of thumb. To reiterate what you're
suggesting: Assume you have a ProductsController. To adhere to the
SRP, the ProductsController should really have no knowledge of what a
Vendor is or how to get it. Consequently, as soon as Vendors come
into the picture, it should be the responsibility of one level higher
(the service layer in this case) to coordinate this cross-domain
responsibility. You'd replace the dependencies in the constructor
with a service to handle these kind of cross-domain responsibility
concerns.

You've convinced me that this is a good idea as soon as you start
introducing cross-domain concerns and breaking the SRP of a single
controller. My biggest concern now is organization. As Kyle implied
earlier, this is more of a view related service (i.e., a data
retriever/processor for the view) rather than a domain related service
(e.g., a calculator which might use various domain objects for
calculating roll up information). Hunting around, I've found that
Evans agrees and calls these application and domain services,
respectively. To make the line more distinct from a S#arp
Architecture perspective, services could be broken down into those
that can be and are only used by controllers, and those services which
can be used by the domain layer on up.

For the services that are used by the controllers, I would see it
necessary to introduce a new class library called
MyProject.ApplicationServices so that the services are not aware of a
web context and so that there is a single directional dependency from
MyProject.Web.Controllers to this class library. What would the
naming convention be for the service that assists, for example, the
ProductsController? Perhaps ProductManagementService.cs? You
wouldn't want it to be ProductsControllerService.cs because this
services layer should have no clue that it's actually being used by an
MVC controllers layer.

The separation doesn't make as much sense for services that are used
by the domain layer; such as a domain specific calculator of some
kind. The domain layer should have access to these types of services
and the services should be aware of the domain layer. Accordingly, it
seems to me that services used by the domain layer should be found
within MyProject.Core being organized as a reflection of their
purpose. For instance, suppose you had a mortgage calculator which
used a number of domain objects to come up with a result, but is used
by another domain object to report a monthly total...or something like
that. It would be very reflective of the domain to have a subfolder
within MyProject.Core called "Services"; instead, the service would
likely be organized as MyProject.Core/MortgageMgmt/
MortgageCalculator.cs, with or without "Service" at the end of the
class name, or something domain oriented like that.

In Domain Driven Design Quickly, available from InfoQ.com, here's an
interesting section to back up this organizational approach:

"Both application and domain Services are usually built on top of
domain Entities and Values providing required functionality directly
related to those objects. Deciding the layer a Service belongs to is
difficult. If the operation performed conceptually belongs to the
application layer, then the Service should be placed there. If the
operation is about domain objects, and is strictly related to the
domain, serving a domain need, then it
should belong to the domain layer."

Thoughts?

Billy McCafferty


On Feb 20, 11:07 am, Alec Whittington <alec.whitting...@gmail.com>
wrote:
> I agree with Kyle on this one, for the most part. I also am not a believer
> of allowing my controller to have direct access to my repository. I really
> like having that service layer there for not only implementing my business
> logic, but to also serve up DTOs to my controllers, which then sends them to
> the views. Does this add a layer of complexity where there should not be
> one, perhaps in some cases. It has been my experience that "simple" views
> for me are few and far in between. Is it the right way to do things,
> debatable at best since it really is subjective to ones personal tastes.
> 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.
>
> What all this really boils down to is a how-to on "Injecting" a Dependency
> into a controller. You've now got plenty of examples of this so you should
> be set.
>
> Cheers,
> Alec Whittington
>
> ...
>
> read more »

Billy

unread,
Feb 20, 2009, 2:30:03 PM2/20/09
to S#arp Architecture
A nice side benefit to having MyProject.ApplicationServices included
as a class library by default within the VS generated solution would
be that it would make it easier for the community to write code
generator alternatives which could safely assume the existence of this
project within the solution.

Billy
> ...
>
> read more »

Alec Whittington

unread,
Feb 20, 2009, 2:48:46 PM2/20/09
to sharp-arc...@googlegroups.com
Billy,
    you have hit the nail on the head. I had not thought about the services being either application or domain before, just shoving them into one layer. But that makes complete sense that they are separate. Once again, thanks for taking an idea and being able to expand upon it.

Cheers,
Alec Whittington

Neo

unread,
Feb 20, 2009, 2:49:32 PM2/20/09
to S#arp Architecture
I Hadn't think about different purpose services like application and
domain.
But it really makes a lot of sense. Right now I have a separate
service layer
called MyProject.Services. According with your thoughts I should
rename it
to MyProject.ApplicationServices which make a lot of sense to me.

Another thing I have in my project is some service classes regarding
the domain
which I called MyProject.Core.Utils, and this should maybe be renamed
to MyProject.Core.Services.

Well, so I was in the right way.

>"with or without "Service" at the end of the
> class name, or something domain oriented like that."

Without "Service" would be beauty, whereas with "Service" would be
more intuitive.

I would go without the "Service".
> > > > > Simple, yes?  For basic stuff like this,...
>
> read more »

Billy

unread,
Feb 20, 2009, 2:54:52 PM2/20/09
to S#arp Architecture
Neo,

I don't think there's anything wrong with having a folder called Utils
in your Core domain (I have one myself ;). The classes within the
folder may happen to be services, but Utils implies a specific group
of objects, such as StringUtils and such. Renaming your Utils folder
to a very generic "Services" folder might lose the meaning of the
intended scope of your Utils folder. Some people (including myself on
past projects) go as far to pull out the foUtils namespace into its
own project for reusability on other projects...but I'd only do that
when you actually have a need to reuse it on another project.

Billy
> ...
>
> read more »

Neo

unread,
Feb 20, 2009, 4:19:03 PM2/20/09
to S#arp Architecture
All right. I'll keep it. I'll just move out some classes that
are domain services and are inside this folder to another.

Thanks Billy.
> > > > > > >   public ProductsController(IRepository<Product>...
>
> read more »

Luis Abreu

unread,
Feb 21, 2009, 8:56:42 AM2/21/09
to sharp-arc...@googlegroups.com
As always, my opinions are just that: opinions...


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


Luis Abreu

unread,
Feb 21, 2009, 9:05:55 AM2/21/09
to sharp-arc...@googlegroups.com

1. You have your Products repository returning Vendors. Not knowing what

your domain model looks like, I am going to assume you have a Vendor entity
(please correct me if I am wrong) as well as a Product entity. With that
setup, each should have it's own repository. As such, a call to the Vendor
repo should be made to retrieve your list of vendors.

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

Luis Abreu

unread,
Feb 21, 2009, 9:34:15 AM2/21/09
to sharp-arc...@googlegroups.com
I dunno, it's rare in my experience that any page stays simple for long. In
which case, I find it easier to start from a service object always and
return a DTO always. These can be simple pass-throughs but when things get
more complex, you can add to them without breaking dependencies. Even in
simple CRUD scenarios, consider a product edit view. At first, you need a
product repository and nothing else. Then the customer wants to select the
categories from a drop-down. Then he wants to see the quantity on hand, then
a breakdown of this by region. All the while, you're adding repositories to
your controller whereas if you started with a service (and it's a
presentation-specific service, not a domain service) that calls
GetCustomerEditData, you don't need to change the controller from its
original form.


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

Luis Abreu

unread,
Feb 21, 2009, 9:40:57 AM2/21/09
to sharp-arc...@googlegroups.com
Hello again.


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

Alec Whittington

unread,
Feb 21, 2009, 11:53:56 AM2/21/09
to sharp-arc...@googlegroups.com
Once again, just opinions


1. You have your Products repository returning Vendors. Not knowing what
your domain model looks like, I am going to assume you have a Vendor entity
(please correct me if I am wrong) as well as a Product entity. With that
setup, each should have it's own repository. As such, a call to the Vendor
repo should be made to retrieve your list of vendors.

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?


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. 


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..


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.

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.


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. 

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.


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?

As always, good conversation Luis.

Cheers,
Alec Whittington

Alec Whittington

unread,
Feb 21, 2009, 12:04:17 PM2/21/09
to sharp-arc...@googlegroups.com
I guess we're talking about services that coordinate work on the domain,
right?


Well as Billy brought up, there are Application Services and Domain Services. I believe in this case, this could fall under either, it would depend on whether the controller was using a single repository or multiple repositories. 


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
.

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.

Cheers,
Alec Whittington

todd brooks

unread,
Feb 21, 2009, 9:27:27 PM2/21/09
to S#arp Architecture
Alec,

Thank you so much for the detailed replies...and same goes for Luis
and everyone else.

For the most part, I agree with DTOs, although I'm not 100% my
implementation of those is how it really should be done.

I would really like to see an implementation of a correctly
implemented service layer , complete with dependency injection and
some DTOs integrated with S#arp. Ie., a more detailed example
application than the fairly trivial Northwind example (no offense,
Billy...I'm not raining on all your hard work).

Alec, as implementations go, what dependencies does your service layer
have? How do you use DI with the controller?

Many regards,

todd

On Feb 21, 10:53 am, Alec Whittington <alec.whitting...@gmail.com>
wrote:
> one is nothing more than a habit for me. [?]
>  360.gif
> < 1KViewDownload

Luis Abreu

unread,
Feb 22, 2009, 4:13:31 PM2/22/09
to sharp-arc...@googlegroups.com

Well as Billy brought up, there are Application Services and Domain
Services. I believe in this case, this could fall under either, it would
depend on whether the controller was using a single repository or multiple
repositories. 

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

Luis Abreu

unread,
Feb 22, 2009, 4:13:31 PM2/22/09
to sharp-arc...@googlegroups.com
Hello again.

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


Jonathan Parker

unread,
Feb 22, 2009, 10:23:25 PM2/22/09
to sharp-arc...@googlegroups.com
Yep, if you are doing YAGNI you are saying "I have no idea what the
customer will want later on". If you are planning ahead you are saying
"I have a pretty good clue about what the customer will want later
on."

I think in both scenarios you taking an extreme position. Maybe it's
up to someone else to make the decision as it is a business risk.

Kyle Baley

unread,
Feb 26, 2009, 12:42:15 AM2/26/09
to sharp-arc...@googlegroups.com
Just discovered one use of DTOs. The Edit actions for the CRUD controller has the following signature:

public ActionResult Edit( int id, DomainObject domainObject )

I'd prefer it to be this:

public ActionResult Edit( DomainObject domainObject )

After all, we have the ID for the domain object already, along with all the other properties. But the reason the id needs to be passed in separately (I think) is because the ID property is protected for Entity objects. So we can't use the MVC automatic model binding. I.e. while all the other properties are set when this action is executed, the ID is not, presumably because the model binder is not able to do so.

Instead, I created a DTO with a public setter on the ID and the signature is now:

public ActionResult Edit( DomainObjectDto domainObject )

In the corresponding DomainObjectForm.ascx page, I changed the HTML so that the hidden field is named DomainObject.ID, instead of just id. Now, the fully constituted DTO is passed into the controller. Modify the first line of this action to use the DTO's ID and you're all set.
Reply all
Reply to author
Forward
0 new messages