views:

201

answers:

3

I've been working with S#arp Architecture but this can probably be applied to any DDD architecture (Domain / Core, Application Services, Infrastructure, and Presentation).

There are many ASP.NET MVC examples that show the controller operating on the domain model through repository interfaces. In fact, the S#arp Architecture tutorial has the StaffMembersController referencing IStaffMemberRepository where it calls FindAllMatching (implemented in the repository). The StaffMember entity, also in the domain/core layer, looks like a data bag with properties and minimal validation on the properties.

Let's say you have a controller that is getting bloated with things that look like business concerns. After reading Microsoft's "Designing Business Entities" chapter in Microsoft's Application Architecture Guide, I believe these concerns could be called "Domain Services".

I want to put these domain services in the domain/core layer but I'm not sure where they should go. Should I create a services folder in the domain/core project that hosts interfaces with an implementations folder underneath it? That seems like a good approach, but I want to see how others have handled this.

Thanks!

+2  A: 

Personally, I'm not a fan of how S#arp Architecture (at least, in their demo projects) has the controllers talk directly to the repositories. My $0.02 is that the domain services should be the interface between controllers and repositories. The repositories exist strictly to abstract away the database (e.g., so that you can replace it with, say, LINQ to Objects during testing). The domain services implement your business logic. You want to be able to test those without connecting to a database, or having to mock out your entire session.

An example that I think gets this right is the MVC project developed in Mark Seeman's book, Dependency Injection in .NET.

Craig Stuntz
I agree that the explicit references to repositories in the controllers seemed like a code smell but everyone was doing it. I'll see if I can get my hands on that book (unfortunately it's not in Safari). Thanks for the input Craig.
Mayo
I agree. Beyond a minimal level of complexity in a project, you need a layer to pull things together from various repositories and apply other business logic / do other magic that doesn't make sense to be in a repository. If the controllers talk to the repository in some cases (for simplicity), but via a service in other cases, you have a mess.
Nik
All of the S# team agree that the sample Northwind example is not a realistic sample of how it should or would be done in the wild. Take a look at the Who Can Help Me sample app. This shows a very nice example of how it can / should be done (arguably). We are working on having another sample for the 2.0 release that will also address this area. As others have already pointed out, you really just need to add a service layer. This is where the controllers should call into. The services are responsible for business logic and repo access.
Alec Whittington
+3  A: 

We built a real world ecommorce platform based on Sharp Architecture and created a demo project that showcases the architecture we put in place. This added the ViewModels, Mappers & a Task layer which helps separate concerns. This is going to form the core architecture of Sharp Architecture v2.0

See http://whocanhelpme.codeplex.com/ for more details.

HowardvanRooijen
+5  A: 

What you're calling Domain Services in your question are what I would call Application Services. This kind of confusion over the three different types of service (application, domain and infrastructure) is what lead to the term "Tasks" being used in Who Can Help Me? (instead of application services).

Broadly speaking, I see domain services as actions/behaviours within the domain that don't belong to any single entity - this is pretty much as described in the Evans DDD book. Application services are more of an orchestration layer/facade over the domain that allows an application to interact with the domain without needing to know the full detail about how it works.

So I believe you need an application services layer to remove the bloat from your controllers. This is the approach that's shown in WCHM and it's the one I now follow in my apps.

In terms of where they should live - I'd send to say you should have them in their own project. If you're being purist about it, the contracts should also live in their own assembly, which means that if you like, you can remove all knowledge of the domain from your controllers. However, the WCHM approach places the contracts in the Domain project, and allows the controllers to have knowledge of the entities. Some people complain about this but it's basically just a compromise.

Hope this helps Jon

Jon