Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD / DI (Unity) / .NET / Composition Root - Domain Services

I have a standard Order/OrderLineItem setup.

A number of Refunds are generated during the day that are persisted during the day, the Refund consists of a an Order Id and 1 or more LineItemId's. I need to consolidate these (in a Windows Service) at the end of the day refund to Credit Cards, Gift Cards, Reward cards etc. as appropriate.

I've been reading Mark Seemann's book and can see the benefit of using a Composition Root to rustle up an object graph.

The consolidation process itself is where I need to do the most composition.

What I don't understand is exactly where this consolidation logic should end up? Can I assume that regardless of where the consolidation logic ends up I still only use something like Unity in the composition root and that composition should happen very early on?

Happy to supply more info or clarify as appropriate!

like image 468
inthegarden Avatar asked Nov 04 '11 16:11

inthegarden


2 Answers

The consolidation process itself is where I need to do the most composition.

So, you mean that process of creating data in your system is where the most domain objects will be created?

That makes sense, and is in line with most applications.

What I don't understand is exactly where this consolidation logic should end up?

The consolidation logic will be provided by one or more service components, that likely utilizes one or more repository components and one or more unit of work components. That service will be composed in the composition root, as will any repositories/units of work you end up creating.

The data itself is completely dynamic. You can't structure your application to know the data's layout statically, thus you can't compose it in your composition root. Nor should you try to. Instead your code might use an ORM to define or map to the relational schema between your domain data objects.

Then you can use the repository/unit of work to retrieve data from storage. You also use your UI/service to create new data using new - no shame in that for domain objects that are purely data, and are guaranteed to have no dependencies. Persist new or modified data to the repository/unit of work.

If this makes you cringe, you can always use a factory pattern that is injected from the composition root to create those objects. But if you've structured your low level domain objects to be DTOs, this won't buy you much, if anything.

So you don't have to use Unity to provide everything, and you don't have to create absolutely every object in your system in the composition root. But you should try to compose static pieces of your system, or even statically configurable dynamic pieces of your system in the composition root. This maps very well to DI containers like Unity.

like image 148
Merlyn Morgan-Graham Avatar answered Nov 06 '22 10:11

Merlyn Morgan-Graham


In case your Refund items are just data containers or entities that do not have any dependencies to services you can simply create an instance using new.

If they have dependencies and must be created by your IoC container and you can't do at startup than you will want to use a factory interface. This factory interface contains a CreateRefund method taking all required parameters that you want to pass to the created instance. This interface is defined in the namespace/assembly of its consumer.

The implementation of this interface depends on the IoC container. Some containers provide the functionality that the interface is implemented automatically by the container just by specifying it in the configuration. Others like Unity require a manual implementation. This implementation lives in the Composition Root as part of your container configuration. Let the implementation take an instance of the container and use it to create the requested Refund instance.

This way the only place where you access the container is in the Composition Root.

like image 35
Remo Gloor Avatar answered Nov 06 '22 10:11

Remo Gloor