Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rules for accessing services from domain objects

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?

like image 479
sanosdole Avatar asked Jan 07 '13 12:01

sanosdole


People also ask

What are the objects in domain?

A domain object is an entity in the domain layer of your application, eg. an Address class. "Model" means the same thing - an entity in the "Domain Model". A POCO (plain old CLR object) is an object that has no behaviour (methods) defined, and only contains data (properties).

How are entities related to Domain-Driven Design DDD )?

A domain entity in DDD must implement the domain logic or behavior related to the entity data (the object accessed in memory). For example, as part of an order entity class you must have business logic and operations implemented as methods for tasks such as adding an order item, data validation, and total calculation.

What is a domain in Domain-Driven Design?

“Domain” in Domain-Driven Design officially refers to a “sphere of knowledge and activity around which the application logic revolves”. In other words, the “Domain” is what is commonly referred to as “business logic” in the software world.

How is entity defined in DDD?

In domain-driven design, an entity is a representation of an object in the domain. It is defined by its identity, rather than its attributes. It encapsulates the state of that object through its attributes, including the aggregation of other entities, and it defines any operations that might be performed on the entity.


1 Answers

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.

like image 55
MikeSW Avatar answered Sep 17 '22 04:09

MikeSW