Introducing a service layer (+ how DTOs/Validation fits in)

20 views
Skip to first unread message

jamesc

unread,
Feb 12, 2009, 12:33:53 PM2/12/09
to S#arp Architecture
Hi everyone,

I've just been introduced to the S#arp Architecture project, and it
looks great! I'm in my early stages of wrapping my head around DDD,
and so wanted to ask your advice. Apologies if these have been asked
before... I did have a dig around in your message history but couldn't
find anything that quite answered my question.... I won't be in the
slightest bit offended if you just point me to some relevant old
messages!

At the moment in the Northwind sample you guys don't have any service
layer in place. I'm assuming I'd place this between the controllers
and the repositories, and the controllers only ever talk to the
service layer, and never beyond.

I've got a questions on this though:

- Would you pass seperate DTO objects, or just domain objects through
to the controllers? Having seperate DTOs feel like they could be
overkill? When would you choose to use one?
- At what point does validation kick in? As I understand it, following
DDD its fine to pass "invalid" domain objects around. does the
repository validate before it stores it? does the service layer
validate before passing it to the repository?
- If say, as a result of a particular object being stored in a
particular state, an email needed to be delivered... this would take
place in the service layer?

Any input on the above would be much appreciated.

Kind regards

James

Scott Leckie

unread,
Feb 12, 2009, 2:05:35 PM2/12/09
to sharp-arc...@googlegroups.com
Hi James

I can respond on two of your questions, but I haven't yet got my head around
validation - I'm still throwing exceptions / returning null from my service
layer (will get to validation in a few weeks!).

I started by passing domain objects around but quickly reverted to DTOs,
particularly because I use WCF and this created a dependency on the (heavy)
domain model being present in the WCF client app. The model is client app
(traditional Windows Service) / WCF Client --> WCF Server --> Services Layer
in #Arch, which then accesses the repository.
In the Web front end, I have (as you suggest) Controller -> Service Layer ->
Repositories.

For your third query; yes, I would put this kind of functionality in the
Services Layer. As far as I see it, the Services Layer can cross a number of
domain objects and may also have input/output to the real world. I've got it
into my head that, at some point, I'll investigate WWF (the Workflow
Foundation, not the guys who save pandas...) and that my Services will
"simply" kick off an external workflow that would do things like send
emails, trigger events to other systems, etc. That would take a lot of the
latency out of the Service Layer.

Cheers
Scott

Scott Leckie

unread,
Feb 12, 2009, 3:19:25 PM2/12/09
to sharp-arc...@googlegroups.com
Actually, I may have under explained my point about the service layer
sending emails.

If an app needs to have very low latency (particularly true for a UI app
such as a website) then you don't want the Service Layer performing lengthy
operations when called from that app. So if, for example, you reckon sending
a single email is pretty quick, then you may want to put it directly in the
Service object that is called by the controller.
If, on the other hand, the operation could be lengthy (and you also need to
bear concurrency in mind) then that Service object should *not* perform that
operation.

What I do right now is that I provide Services above the repositories but
the Services that are called from the Controllers will only do database work
(simplistically...). Anything which involves talking to external systems
(emails, WMI, pinging, running external commands, etc) are queued. Right
now, I use a database table (up through NHibernate, into a Domain Object,
Repository and yet another Service) to store the job requests.
There is then a separate app (traditional Windows Service) that also
leverages #arch to retrieve its jobs and execute them. Some of these jobs
are "internal" (e.g. sending an email) and some are external (e.g. calling
an external command to run a task).

I do all of that within what I would call the Service Layer so, in the
context of MVC;

View
|
Controller
|
Service
|
Repository -> Domain <- Database/NHibernate


The standalone apps are (as a Windows Service);

App logic
|
(optional WCF)
|
Service
|
Repository -> Domain <- Database/NHibernate


It's that job table that I want to migrate to Workflow Foundation at some
random point in the future.

Hope that all makes sense.

James Crowley

unread,
Feb 13, 2009, 5:12:12 AM2/13/09
to sharp-arc...@googlegroups.com
Thanks for your advice Scott - that all makes sense! I can see how
you'd switch to DTOs if the objects have a lot of overhead from WCF. I
think for the moment as I'm just using "POCO" then for the moment I'll
pass those straight through to the controllers... and re-evaluate if
things get painful.

Does anyone have any advice on the validation side of things? :)

James

2009/2/12 Scott Leckie <scott....@elbest.net>:
--
James Crowley
Managing Director
Developer Fusion - Connecting developers worldwide

Developer Fusion Ltd | 58 Sandringham Close | Enfield, EN1 3JH
mob: 07986 624128 web: http://www.developerfusion.com/

Neo

unread,
Feb 13, 2009, 12:54:10 PM2/13/09
to S#arp Architecture
In the project I'm managing here, I've already noticed and tried to
tell you guys, we should need a service layer.

I dont think its meaningful to allow the controller to talk with the
repository layer. That's why we already created
a service layer between controllers and repositories.

All validation is being done at service layer. So, if someday we
decide to port our application as a WinForms, it'll be
much easier, since all functionality and business rules are inside a
separated layer.

All services responsible for communication with the repositories
inherits ServiceBase<RT, T, IdT>:

abstract class ServiceBase<RT, T, IdT> : IRepositoryWithTypedId<T,
IdT> where RT : IRepositoryWithTypedId<T, IdT> where T :
IEntityWithTypedId<IdT>, IValidatable

I didnt have any problem with this approach. And it looks pretty
straightforward.

If you need any help or suggestion regarding my approach its all
welcome :)

On Feb 13, 8:12 am, James Crowley <james.crow...@gmail.com> wrote:
> Thanks for your advice Scott - that all makes sense! I can see how
> you'd switch to DTOs if the objects have a lot of overhead from WCF. I
> think for the moment as I'm just using "POCO" then for the moment I'll
> pass those straight through to the controllers... and re-evaluate if
> things get painful.
>
> Does anyone have any advice on the validation side of things? :)
>
> James
>
> 2009/2/12 Scott Leckie <scott.lec...@elbest.net>:

Jonathan Parker

unread,
Feb 13, 2009, 10:44:28 PM2/13/09
to sharp-arc...@googlegroups.com
Also AFAIK IPSEC requires that the web server doesn't directly access
to the DB server.

wgp...@gmail.com

unread,
Feb 13, 2009, 11:53:32 PM2/13/09
to S#arp Architecture
I agree with Neo.

Given the current framework, there will no doubts be folks passing 10
IRepositories into the constructor of a given controller. The same
argument made by Billy with regards to not having controllers in the
same project as the views seems to apply here. Sure, a service layer
shouldn't be required ... but it should be recommended, encouraged and
thus the default.

Neo, it might be interesting to post a writeup on how your
implementing a service layer with sharp arch. on the wiki (at least, I
know I'd be interested).

Ikhwan Hayat

unread,
Feb 14, 2009, 8:11:25 AM2/14/09
to S#arp Architecture
Hi,

If we introduce a Service layer between the Controller and the
Repository, do we restrict the Controller from accessing Repositories
directly?

I'm currently having this kind of architecture in my app (even before
#arch). Right now my current practice is to allow controllers to
access repositories directly. The argument is, for simple CRUD ops,
it's kinda cumbersome to create a service to wrap those simple
operations.

But that brings in another problem. When working in a team, sometimes
it's not clear whether somebody else has created a service for
something or we should use the repositories directly. This can bring
confusion.

So, I'm thinking of doing something like this. There will be no
"custom" repository. If you want to do any operation, create a service
for that or modify an existing one, then in there, always use the
generic repository for everything. This is actually combining the
service layer and repository into one. What I'm not still not sure is
whether it's a good idea to do this because it will make the service
layer tightly-coupled with NHibernate.

What's your opinion on that? Thank you.

Scott Leckie

unread,
Feb 14, 2009, 8:59:32 AM2/14/09
to sharp-arc...@googlegroups.com
I agree - keen to see Neo's implementation.

As a simple hobbyist, I've implemented my own but not from the perspective
of any "good practise".

Thanks

lightglitch

unread,
Feb 14, 2009, 10:47:04 AM2/14/09
to S#arp Architecture
I'm also very interested in seeing Neo Service Layer approach.

James Crowley

unread,
Feb 14, 2009, 1:45:43 PM2/14/09
to sharp-arc...@googlegroups.com
Likewise, I'd be very interested to see how people have approached
this. Found an interesting blog entry on this by Ayende -
http://ayende.com/Blog/archive/2007/02/27/Entities-Services-and-what-goes-between-them.aspx

James

2009/2/14 lightglitch <mario....@gmail.com>:

Neo

unread,
Feb 14, 2009, 8:03:03 PM2/14/09
to S#arp Architecture
Hello guys.

Right now I'm in my mother's home, and unable to write a sample of my
approach...

Probably tomorrow I'll be at home, so I can put my effort to write my
implementation
on the wiki.

On 14 fev, 16:45, James Crowley <james.crow...@gmail.com> wrote:
> Likewise, I'd be very interested to see how people have approached
> this. Found an interesting blog entry on this by Ayende -http://ayende.com/Blog/archive/2007/02/27/Entities-Services-and-what-...
>
> James
>
> 2009/2/14 lightglitch <mario.ffra...@gmail.com>:

Billy

unread,
Feb 15, 2009, 2:05:37 AM2/15/09
to S#arp Architecture
Add one more person to the list of people interested in checking out
your approach Neo. ;) I've tried a couple of service layer
implementations and I feel that they've introduced too much
complexity, are difficult to change, and are hard to understand
quickly. (I'm talking about in non-trivial, real world situations.)
So needless to say, I'm looking forward to taking a look at your
ideas. Tell your mom we said hi!

Thanks!
Billy

Kyle Baley

unread,
Feb 15, 2009, 6:21:05 PM2/15/09
to sharp-arc...@googlegroups.com
I kind of prefer having a service layer in their as well though I haven't worked on projects substantial enough to justify them just yet. The only part I didn't like was the translation 'twixt DTOs and domain objects but I'm hoping Jimmy Bogard's AutoMapper will help the next time I need to do that. http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx

Luis Abreu

unread,
Feb 16, 2009, 9:00:30 AM2/16/09
to sharp-arc...@googlegroups.com
> Given the current framework, there will no doubts be folks passing 10
> IRepositories into the constructor of a given controller. The same


10 repositories? Wow...

Luis

Billy

unread,
Feb 16, 2009, 11:32:39 AM2/16/09
to S#arp Architecture
I don't typically get defensive ;), but I wouldn't see this as
symptomatic of a design problem within #Arch but as a design problem
within the project application itself. Someone passing 10
repositories to a controller is simply making the controller do too
much with an excessive violation of the SRP. The developers should
ask themselves if they're over-complicating the logic or if they're
going to be confusing the user. Appropriate resolutions would include
splitting the responsibilities across more controllers, using
subcontrollers, or, as you've suggested, introducing a service
object. But introducing a service object doesn't necessarily resolve
the problem; it may simply move the too-many-dependencies-for-one-
purpose to another location. Adding another layer of indirection to
carry the burden of a gross violation of the SRP, in this case the
introduction of a service object, doesn't necessarily make the problem
better; in fact, it may often lead to a confusing design, increased
rigidity, while being more prone to bugs.

On my current project, we got a little lazy and ended up passing a
bunch of dependencies (probably close to 10 in fact - hey, it
happens ;) to a controller in one instance that we didn't properly
think out. We ended up introducing service objects (within a service
layer) to carry the burden of this overly complex form. The service
objects for this controller are now a painful point of maintenance in
the application reflecting the negative properties of grossly
violating the SRP. The service layer didn't reduce the smell, it
simply moved it to a "more appropriate layer for dealing with that
kind of stuff." Not surprisingly, the UI that the controller supports
is overly complex as well (violating the "don't make me think" UI
pinciple ;).

In conclusion, too many dependencies (with an upper limit of around 6
or 7?) is often a symptom of an overly complex approach to a given
situation. Perhaps the controller is doing too much and/or you're
expecting too much of the user who will be working with the UI which
the controller supports. The introduction of a service layer
shouldn't be used as a means of brushing design problems such as this
under the rug. I'm not suggesting that a service layer should not be
used, only that developers should ask themselves if the introduction
of service objects are leading to a simpler and more maintainable
design, or if it's in fact simply adding more spaghetti to the pasta
bowl.

Billy "expect a blog post on this" McCafferty ;)

Luis Abreu

unread,
Feb 16, 2009, 4:38:37 PM2/16/09
to sharp-arc...@googlegroups.com
Service can be used for coordinating work, but only when that coordination
is needed. Is that the case you're mentioning?

> -----Original Message-----
> From: sharp-arc...@googlegroups.com [mailto:sharp-
> archit...@googlegroups.com] On Behalf Of Billy
> Sent: segunda-feira, 16 de Fevereiro de 2009 16:33
> To: S#arp Architecture
> Subject: Re: Introducing a service layer (+ how DTOs/Validation fits
> in)
>
>

Billy

unread,
Feb 16, 2009, 5:00:35 PM2/16/09
to S#arp Architecture
Absolutely...I certainly don't want to imply that I'm against the use
of a service layer. As you mention, it's ideal for handling
coordinate efforts that leak into controllers. But if the controller,
or service for that matter, requires 10 repositories, it's likely a
sign that the design and scope-of-responsibility of the service should
be reconsidered.

Billy

Col Dunn

unread,
Feb 16, 2009, 6:50:33 PM2/16/09
to S#arp Architecture
As well as interested in Neo's thoughts on a service layer, I would
also be interested on how to implements the sub-controllers you
mention Billy.

The talk is interesting me about passing in too many repositories...
What would you suggest in the simple case of having a lot of drop
downs on a page, each sourced from a database?

Col.

martin

unread,
Feb 16, 2009, 7:27:21 PM2/16/09
to S#arp Architecture
I know it is controversial and in the futures assembly.
But I still maintain the best way of retrieving data from a different
controller is to use the RenderAction method.
I know that the purists feel it violates the MVC pattern as the View
is requesting more view.
But I personally feel that it is less complex elegant solution than
subcontrollers and keeps the seperation of concerns within the
controllers.

Neo

unread,
Feb 17, 2009, 4:20:02 PM2/17/09
to S#arp Architecture
As promised, here's the post about the service layer I've talked
about.

http://nicecode.wordpress.com/2009/02/17/introducing-sharparchitecture-service-layer/

Maybe its not an ideal approach. But maybe it can cast some ideas for
us.

Martin Hornagold

unread,
Feb 18, 2009, 3:48:40 AM2/18/09
to sharp-arc...@googlegroups.com
Neo,

I am a little bit confused by this implementation.
If this class implements a repository interface then is it not just an
alternative repository?

-----Original Message-----
From: sharp-arc...@googlegroups.com
[mailto:sharp-arc...@googlegroups.com] On Behalf Of Neo
Sent: 17 February 2009 21:20
To: S#arp Architecture
Subject: Re: Introducing a service layer (+ how DTOs/Validation fits in)


Neo

unread,
Feb 18, 2009, 3:19:29 PM2/18/09
to S#arp Architecture
Not exactly an alternative... If we will wrap the repository our
service should have
the repository methods exposed. The difference from the service and
the repository
is that the service will manage some methods differently, having
responsibility over
validation and the direct access to the repository.

Services which doesn't need to expose repository will not implement
the ServiceBase.
It will just have its own interface and implement it.

Maybe it was not the best approach, or a good one either. Probably
Billy has a better
idea in mind :)

Anyway, that's what I'm going with by now.

On Feb 18, 5:48 am, "Martin Hornagold"

Luis Abreu

unread,
Feb 21, 2009, 9:15:27 AM2/21/09
to sharp-arc...@googlegroups.com
I've just finished reading the post. Here are my comments on it:

You say :" As discussed in this post, I don't think its a good practice to
let the controller talk directly with the repository. The controllers are
specific to the MVC pattern and the MVC library, which means that if we put
validation rules within the controllers, it will be pretty hard to migrate
our project to be used on winforms for example."

This absolutely correct, but I don't agree that having the controller talk
directly to the repositories means that you have to put your validation
rules on the controller. Here's a quick example of some code that could go
on a controller's action method:

var user = GetUserThatIsBeingUpdatedFromSomewhere();
UpdateUserWithFormInfo(user);
var brokenRules = user.GetBrokenRules();
if( brokenRules.Count() > 0 ){
//fill error info
//probably interact with modelstate, etc, etc
}
var repository = Repositories.Get<User>();
var success = repository.Save(user);
//check for success and do other stuff

Ok, this is just a snippet I've written here and you could really improve it
by adding exception handling, etc. As you can see, the controller is using
the domain objects directly without any problems or validation concerns.

Luis

Simone Busoli

unread,
Feb 21, 2009, 9:44:23 AM2/21/09
to sharp-arc...@googlegroups.com
that's because you put the validation on the domain entity, which might or not be a good thing.

Luis Abreu

unread,
Feb 22, 2009, 5:46:08 AM2/22/09
to sharp-arc...@googlegroups.com

And why is that? I’m really interested in hearing more on why this is a bad idea because I’ve tries all the approaches that have been commented here and this is the one that works best. We can go into a discussion on the advantages/disadvantages of using this option, but my main point with my previous mail is show that it is possible to have validation without a service and that is not also in a controller.

 

Luis

 

From: sharp-arc...@googlegroups.com [mailto:sharp-arc...@googlegroups.com] On Behalf Of Simone Busoli
Sent: sábado, 21 de Fevereiro de 2009 14:44
To: sharp-arc...@googlegroups.com
Subject: Re: Introducing a service layer (+ how DTOs/Validation fits in)

 

that's because you put the validation on the domain entity, which might or not be a good thing.

Simone Busoli

unread,
Feb 22, 2009, 11:27:12 AM2/22/09
to sharp-arc...@googlegroups.com
Hi Luis, I'm not an expert on this topic. I read something lately, Billy wrote a blog post as well about it, in reply to agile joe.
I think the best way to ask this sort of question is either the alt.net or ddd mailing lists.
But here's my take on it. In the beginning having the validation on the entities sounded right, but then you might have rules which need a repository to be validated (two users with same username), so how do you deal with it? Do you inject the repository in the entity? Do you inject it on the Validate() method? I'm not sure.
On the other hand, as I've seen doing, and I think the sample northwind project does as well and I'm sure CodeCampServer does, the validation is at controller boundary, you validate the dtos, which I don't like very much, since I think that validation should be a domain concern.
Another option is to use a domain service to enforce validation, that sound cleaner, but I'm not sold on using a service just to enforce validation. I'd like to hear other opinions on the topic.

Luis Abreu

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

Hi Luis, I'm not an expert on this topic. I read something lately, Billy
wrote a blog post as well about it, in reply to agile joe.

I'm not an expert either but had to play with several options in my last
project.

I think the best way to ask this sort of question is either the alt.net or
ddd mailing lists.

Agreed. I've had some interesting discussions there on this subject a few
months ago...

But here's my take on it. In the beginning having the validation on the
entities sounded right, but then you might have rules which need a
repository to be validated (two users with same username), so how do you
deal with it? Do you inject the repository in the entity? Do you inject it
on the Validate() method? I'm not sure.

That is correct, but things start to look better when you don't think about
repositories and think about validations as services which are injected into
your aggregates. In practice, the classes that implement these services
might end up using repositories internally, but the entity interacts with an
existing validation service, not with the repository. I generally do this
because it makes validation more expressive. Again, in the repetition
scenario, you probably don't need to use a repository since you only need to
perform a check against your db (if you're using them).


On the other hand, as I've seen doing, and I think the sample northwind
project does as well and I'm sure CodeCampServer does, the validation is at
controller boundary, you validate the dtos, which I don't like very much,
since I think that validation should be a domain concern.

It's not really correct to validate DTOs (beyond those typical simple tests
where you test those basic rules) because your domain logic should be on
your domain layer, not scattered through controllers. On the other hand, I
guess this is OK if you're developing a simple app and your domain is only
going to be used by that app...

Luis


Simone Busoli

unread,
Feb 22, 2009, 5:07:27 PM2/22/09
to sharp-arc...@googlegroups.com
That is correct, but things start to look better when you don't think about
repositories and think about validations as services which are injected into
your aggregates. In practice, the classes that implement these services
might end up using repositories internally, but the entity interacts with an
existing validation service, not with the repository. I generally do this
because it makes validation more expressive. Again, in the repetition
scenario, you probably don't need to use a repository since you only need to
perform a check against your db (if you're using them).

I'm not sold either in injecting anything into the entities. I've read several posts today as well, and it looks like there's some agreement that validation should be left out from domain entities and moved somewhere else, using specifications and a validation service which executes them and reports validation errors. But I'm not sold either. On the application side, how do I know what I have to do with those validation services? Are they to be used standalone, are they to be wrapped into a domain service which ensures everything is valid when persisting data? I heard Greg Young on InfoQ speaking about having always valid entities. I'm pretty sure he knows what he's saying, but I have a hard time figuring out how you would accomplish that when the validity of your entity depends on something external to your entity. This might start to make sense once you start using commands to make changes to your entities, as Greg advertises, but I don't think I'm going thus far.

Luis Abreu

unread,
Feb 22, 2009, 5:29:20 PM2/22/09
to sharp-arc...@googlegroups.com

I'm not sold either in injecting anything into the entities. I've read
several posts today as well, and it looks like there's some agreement that
validation should be left out from domain entities and moved somewhere else,
using specifications and a validation service which executes them and
reports validation errors. But I'm not sold either. On

My main problem with this is "forcing" a user to know the sequence of calls
it should perform when using my DDD library. By putting it on the entity,
he'll know that he can check for validity by calling a specific method.
Injecting it there is generally hidden form theclient if he's using the
factories and repositories for creating and saving aggregates.

they to be wrapped into a domain service which ensures everything is valid
when persisting data? I heard Greg Young on InfoQ speaking about having
always valid entities. I'm pretty sure he knows what he's saying, but I have
a hard time figuring out how you would accomplish that when the validity of
your entity depends on something external to your entity.

I'd say that you've got two levels of validation: "individual validation",
where all that matters is that the aggregate's data is valid and "collective
validation", where you also need to ensure that you don't have duplicate
aggregates, etc...

This might start to make sense once you start using commands to make changes
to your entities, as Greg advertises, but I don't think I'm going thus far.

Btw, one of the things I see commands doing is improving scalability...I've
run some tests with it but I need more time and more reading material for
understanding everything he's saying :)

Luis


Simone Busoli

unread,
Feb 24, 2009, 3:54:49 PM2/24/09
to sharp-arc...@googlegroups.com
Definitely. I don't have much substance to play with now, so I guess I'll have to delay any further consideration until I have something concrete to put my hands on. Nevertheless, this is an intriguing topic.
Reply all
Reply to author
Forward
0 new messages