2

I've been looking into Ioc containers and AOP recently, and I'm pretty amazed by the concepts. I'm struggling however to decide how and where to implement the container.

The articles below suggest implementing the container in the 'application entry point':

Now - my thought-experiment application will consist of multiple visual studio projects ( one for data access, winforms application ). And let's say I want to use AOP for logging with Log4net, and so I setup log4net in the Ioc container. So WinForms application in entry point, that's where Ioc container should go.

Here's the question: if I want to log stuff in my data access project/layer, should I add a reference to my winforms application, get the ioc container from there, get the log4net instance out of it and use it for logging?

That would mean my data-layer depends on winforms application, that can't be right. How about I put the container is something like a 'Common' project within the solution. That way, all related projects (Data access/winformsa etc.) can access the container. What is the right way to go here?

Rubén
  • 34,714
  • 9
  • 70
  • 166
Jochen van Wylick
  • 5,303
  • 4
  • 42
  • 64

2 Answers2

6

Your application's Composition Root would be the Windows Forms project. This is the only project which should have a reference to a DI Container.

In all other projects, dependencies should be injected via Constructor Injection. All decent DI Containers understand this pattern and use it to Auto-wire dependencies from the Composition Root.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • 'only' is a strong word :) modules/registries/installers can help keep things sane and encourage multiple IOC-aware projects.. But as a first step getting to a single project is the right thing to do. – Nicholas Blumhardt Nov 06 '11 at 15:35
0

I've abstracted my container into a separate assembly that all other assemblies / projects depending on its services reference. The container project has just a single class and - more or less - a single method:

public class MySpecialContainer
{
     public T Resolve<T>() { // ... Get stuff from the IoC container }
}

The container build would either occur in MySpecialContainer's ctor or just add another method like Initialize() or some such.

The only problem is this approach broke down for me when I used Autofac and had both a Windows Service and ASP.Net project needing the container. Each had its specific requirement for scoped-lifetime services: Windows Service - PerLifetimeScope, ASP.Net - PerHttpRequest. I guess I could've passed in an argument into MySpecialContainer that denoted which scenario to configure for but I decided just to take on an Autofac dependency directly.

The good news is, if you stick to ctor injection, then you can very easily swap out various container implementations - Autofec, Ninject, StructureMap, etc.

xanadont
  • 7,493
  • 6
  • 36
  • 49