views:

322

answers:

1

I have a 3-tier .NET service app, which follows the standard approach:

Frontend -> Object Model / Business Logic -> Data Access

I'm trying to learn about dependency injection along the way, and thus far have found it great (using Autofac). Each of the 3 tiers needs to create an assortment of objects, sometimes with extra configuration/etc. It seems like the DI container should be the ideal thing to solve this, but I'm having some issues seeing where it should live in relation to the rest of the system.

Currently I have a class in the frontend which configures the DI container. It is basically a big bunch of code saying container.Register<SomeType>() and so on.

The problem is, it is configuring the container for all 3 tiers, and hence must have fairly invasive knowledge of the data access layer. Having code in my frontend with such knowledge sets off alarm bells in my head as the point of separating the app into tiers is to avoid this exact situation.
This is also made worse by the fact that my Data access layer isn't just SQL server being a dumb bucket of bits, but is made up of lots of complex COM interop and P/Invoke calls, so has quite an impact on the DI configuration.

I have given some thought to breaking it up - perhaps having one container per tier, or having a "Setup" class in each tier which talks to the global DI container to register it's own bits, but I'm not sure if that will cause more problems than it solves...

I would really appreciate it if anyone could share their experiences in using DI with multitiered apps.

Thanks, Orion.

+1  A: 

This depends on if you have have three tiers (physical separation) or if all your logical layers are deployed together. If the frontend is separate from your BL and communicates through a webservice or WCF then the frontend and the backend needs their own containers because they're running in separate processes or separate machines. The containers would only register its own components and the interfaces of the 'next' layer.

On the other hand if all the layers are running in the same process then you should only have one container. The container would be initialized and hosted in the starting point of the application like global.asax for a web app.

The problem with the container host knowing to much of all the different parts of the system could be solved by not registering the classes one by one, but instead register all types in an assembly. That way you don't need strong references to all assemblies in your solution just to configure the container. Example of how that can be done with Castle Winsdor:

Kernel.Register(AllTypes.Pick().FromAssemblyName("DataAccessLayer.dll"));
Kernel.Register(AllTypes.Pick().FromAssemblyName("BusinessLogic.dll"));
Dala