views:

383

answers:

3

I've been searching for guidance for using IoC containers in domain driven design. Evan's book unfortunately doesn't touch on the subject. The only substantial guidelines I could find on the internet is here.

Many of Malovic's points are common sense but I'm concerned about a few of them. He suggests that IoC container's should be reserved for resolving services only and that using an IoC container to resolve domain dependencies is a bad idea. However, he doesn't back up this assertion with any examples. He simple states it as a matter of fact.

He then goes on to say that mixing IoC containers and factories doesn't make sense. This appears to contradict his first point. If, in fact, domain dependencies shouldn't be resolved by an IoC container how then should they be resolved? Evan's book clearly points to factories as the logical choice.

I would appreciate any input you have on the matter. I'm a novice when it comes to both DDD and IoC. I'm struggling to grasp how IoC and DDD can work together.

+2  A: 

In my opinion he is correct about not using IoC container in domain model. That practice I follow myself as well. Basic idea is that services may contain infrastructure dependencies and therefore its wise to mock them. Domain entities don't have those, so its not important to mock them up (still coding to interfaces is good practice).

Factories for domain entities should not be in IoC container, but factories for services should. Basically you may reference entity factories in your services. It's not very tight coupling.

Good reading about IoC can be found at Billy McCafferty's blog post "Dependency Injection 101"

Marek Tihkan
Could you elaborate on why using IoC containers for resolving domain dependencies is a bad idea? What kind of troubles do you run into it you use them. What do you suggest instead? A factory for each aggregate root and a factory for creating the factories?
codeelegance
First of all IoC container/ServiceLocator is infrastructure and I don't want it in my model. Secondly in my tests I have to configure container to create System Under Test. Thirdly why domain model should even talk to services.I don't think you need so many factories. Sometimes I use Factory Method pattern, but I haven't created much factories themselves. In Evans book its said that factories are for encapsulating value objects and aggregate roots.
Marek Tihkan
"When creation of an object, or an entire aggregate, becomes complicated or reveals too much of the internal structure, factories provide encapsulation." [Evans, DDD, p136] You should not need very much factories, because everything in domain model isn't that complicated.
Marek Tihkan
+1  A: 

IOC containers are invaluable when designing unit-testable code and are orthogonal to DDD. You could create your own implementation of factory and builder patterns if you want...by why go through the trouble?

Absolutely. Use an IOC container that's just powerful enough to meet you specific requirements; no more, no less.

Doug Knesek
A: 

We use DDD, and dependency injection (the pattern), but do not use a dependency injection framework.

One problem with popular dependency injection frameworks is how they separate configuration into XML files. XML is a great markup language. How it became a configuration language, I will never understand. The issue, of course, is that you have to run the application before you know if everything is wired up correctly. It is also hard to see what code is used where. If you are using interfaces, then the only reference to an implementation will be in an XML file, which is harder to spot. And finally you lose type safety and generics. (I once saw a horrible bug in production which would have been caught by the compiler had we not been using XML.)

I should point out that I am not saying that dependency injection is bad. It is a fundamental pattern of good object design. But there is absolutely nothing wrong with doing wiring in a factory.

At my last two projects we have removed large amounts of "code" out of XML files, and into factories. The factories are wired up with container managed services (such as JDBC connections, JMS connections and so forth). The application has become much simpler to understand, because the factory is less verbose than XML. And as a Java programmer, it is much easier to wire together a program using control-space, instead of XML twiddling - and your IDE will highlight when you have broken something.

In an integration test, just create the objects as you would in a factory.

ie,

dbConnection = DatabaseConnectionFactory.connection();    
serviceUnderTest = new PaymentProcessor(new CustomerRepository(connection));
rhys keepence
I've been experimenting with Castle Windsor, which has API support for in-code configuration. container.AddComponent<IMyInterface, MyClass>(). I try to avoid using xml configuration if its not necessary.
codeelegance
StructureMap has Scanner feature, which maps almost automatically. If you want you may create some conventions using reflection to bind services (example implementation can be found http://github.com/marektihkan/Arc/tree/master/Arc/Source/Arc.Infrastructure/Dependencies/Registration/Auto/)
Marek Tihkan