Best practices for configuring an IoC container in Asp.Net MVC Composition Root

I am building an ASP.Net MVC 2 application and I want to follow the ideas of Mark Semann's book โ€œInjecting Dependencies in .Netโ€, so I registered my custom Factory controller in the Global.asax file, and I am configuring the container in the Factory controller as follows:

public IController CreateController(RequestContext context, Type controllerType) { var container = new Container(); object controller; if(controllerType == typeof(MyControllerOne) { container.Configure(r => r. For<IService>(). Use<ServiceOne>()); } else if(controllerType == typeof(MyControllerTwo) { container.Configure(r => r. For<IService>(). Use<ServiceTwo>()); } ...... return container.GetInstance(controllerType) as IController; } 

Now this code works (although it is possible that I may have an error somewhere, since I write it from memory), the dependencies are solved, and each time the correct controller is created with the correct dependency, but it seems that for each request the container is configured to allow dependencies that will be needed at this point. So my questions are:

  • Isn't that redundant?
  • Should the container in Global.asax be configured to run only once? If so, how can this be done?
  • Configuring the container the way I do it, how will the lifetime of the object affect? I mean that in the end there will be repositories that should have a singleton lifetime, some others should be created once with an HTTP request and so on. What could be the consequences?

Any comments, ideas and / or suggestions would be greatly appreciated.

By the way, the IoC container that I use is StructureMap, although I think this may not be very relevant for this particular issue.

+6
source share
1 answer

Indeed, it is redundant to conditionally register each controller upon request. With StructureMap, the Factory controller should look like this:

 public class StructureMapControllerFactory : DefaultControllerFactory { private readonly IContainer container; public StructureMapControllerFactory(IContainer container) { if (container == null) { throw new ArgumentNullException("container"); } this.container = container; } protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType) { return (IController)this.container.GetInstance(controllerType); } } 

All services must correctly register in one instance of the container. As an example, you can register all controllers with StructureMap as follows:

 this.Scan(x => { x.AssemblyContainingType<HomeController>(); x.AddAllTypesOf<IController>(); x.Include(t => typeof(IController).IsAssignableFrom(t)); }); 

This mainly happens after "Register to allow release template . "

+4
source

Source: https://habr.com/ru/post/901040/


All Articles