Rules for accessing services from domain objects
A

1

5

I am comparing the possibilities for using services (in the sense of a process local component like in the Windsor IoC container) from the domain model.

I have 3 ways to achieve this:

  1. Publishing a domain event and having service layer code handling it

  2. Injecting the service through a method on the model object

  3. Injecting the service in the model object

(4. Using a Service Locator)

The first leads to a very expressive and repetive pattern, creating domain events and handlers in a procedural style for otherwise simple tasks. But it has the best decoupling of the model from the environment it is used within (model is self defined).

The second makes methods arguments longer and looks like it breaks encapsulation (if the action of the model object requires other services, all callers have to change).

The third will inject Dependencies that are not required for the current Transaction. Also one needs to "extend" NHibernate for this. I would avoid this method due to other recommendations read.

As i want to write this in our documentation, i need to tell the reader when to use which method. I´m thinking something along the line "Use method injection if you would put the domain event handler into the model assembly", but it does not really hit the point.

Suggestions for this rule?

Approve answered 7/1, 2013 at 12:12 Comment(0)
A
8

If an AR (aggregate Root) needs some data from a service, that data should be taken as a dependency (NOT the service). Basically, the AR won't know about the service at all.

If some method really has a depednency that wouldn't make sense to be injected in the constructor, pass it as method argument. I don't think you should pass the service though (but it depends), pass directly the data required.

If the AR does something which will require a service to update stuff, I think the message driven is the way to go (generate an event).

About NHibernate or other details, an AR doesn't need to know about them. IF it isn't a domain concept, keep it away from the AR.

Personally, I try to model the AR so that it won't need a service. It multiple AR are involved in a scenario, I'll use domain events with a reliable service bus. This means any db transaction is out of the question. I keep the transactional stuff only within AR, more exactly in the AR repository, for everything else there is eventual consistency.

Apocynaceous answered 7/1, 2013 at 12:43 Comment(1)
Very good answer (especially the point with data is notable). I´ll make the rule: "Use domain events". Although i find it quite procedural and repetive for using services that are "Domain Concepts", it is one rule with the least problems.Approve

© 2022 - 2024 — McMap. All rights reserved.