1

I have a 3 layer solution with the following structure:

UI -> BLL <- DAL

The UI is an ASP.NET MVC application. Each controller requires BLL components on its constructor. And each BLL component requires DAL components on its constructor.

In the past I used StructureMap as the IoC container. And on its earlier versions, StructureMap used the ObjectFactory class which was static. Because it was a static class I could use StructureMap on the MVC to replace the default ControllerFactory and then another project where BLL and DAL configurations were made.

On newer StructureMap versions, ObjectFactory has been marked obsolete. I do understand that now I have to provide my own Container instance.

However, I don't have that chain happening without my projects being connected. Furthermore, if I add configurations to BLL and DAL to the MVC project, I will have to reference everything at the UI level which I would like to avoid.

What I think I have to do is to keep two different projects with StructureMap.

One inside the MVC project, responsible for creating controllers. However, I need to figure out a way to delegate BLL instances to the second container, which probably will keep where it is and knows how to create BLL and DAL (so BLL can be created).

The second one (to create BLL components) would look like this:

public static class BLLContainer
{
    public static Container BuildServiceContainer()
    {
        return new Container(x =>
        {
            // This uses the Scan method to locate BLL and DAL
            // interfaces and implementations.
            x.AddRegistry(new DALRegistry());
        });
    }
}

My questions are:

  1. Is it really possible to delegate object creation from my MVC application to the StructureMap container at the BLL level without having to reference additional (unneeded) projects?

  2. If I'm returning a new instance of the container as the code above shows, this means I'm running the scanner for every request to the web server (StructureMap uses PerRequest as the default). How can I avoid that? I can't see how I'm going to prevent that other than going back to a Singleton.

Steven
  • 166,672
  • 24
  • 332
  • 435
Rodrigo Lira
  • 1,489
  • 3
  • 14
  • 28
  • Related: http://stackoverflow.com/questions/9501604/ioc-di-why-do-i-have-to-reference-all-layers-assemblies-in-entry-application – Steven Feb 09 '15 at 06:35

1 Answers1

3

I never used StructureMap, so my answer is not about StructureMap or how you can use it.

When you use dependency injection all comes together around your composition root. This is the place where the complete applcation get's composed so this place is also in need of complete knowledge of your application.

If you really do not want to reference your DAL from the UI, you can place your composition root in a different assembly and reference that assembly from your UI assembly.

But what is the difference? By referencing the BL and DAL assemblies from the UI you're, I.M.O., not doing anything wrong as long as you reference the classes in the DAL only from the composition root and not use them directly in your controller. Other than creating the possiblilty to do that by mistake, there is no real other problem.

Regarding your second question. Your application has to have 1 and only 1 DI container. Splitting this in multiple containers will get you in trouble. The already mentioned blog of Mark Seeman clearly states every application needs a single composition root.

A decent DI container will give you all kinds of options to control the lifetimes of the created objects, so all singletons will not be necessary as long as you give the container the oppurtunity to do so.

My DI container of choice is Simple Injector. You can start reading about this container here. Simple Injector also has a quick start package for MVC and has very enthusiastic community which are always happy to help you.

qujck
  • 14,388
  • 4
  • 45
  • 74
Ric .Net
  • 5,540
  • 1
  • 20
  • 39
  • Thanks for the input. SimpleInjector is simple enough that after reading your answer I already replaced StructureMap. What I did was to initially create the container outside the UI, but the only place calling it is the MVC application in the global.asax as per the blog post about composition root. I did that to prevent DAL to be used in the UI as you said. – Rodrigo Lira Feb 09 '15 at 00:18