在Asp .Net MVC组合根中配置IoC容器的最佳实践

Ser*_*ero 5 c# dependency-injection inversion-of-control

我正在构建一个ASP .Net MVC 2应用程序,我想按照Mark Seemann的书".Net中的依赖注入"中的想法,所以我在Global.asax文件中注册了我的自定义控制器工厂,我在内部配置容器控制器工厂如下:

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;
}
Run Code Online (Sandbox Code Playgroud)

现在这个代码可以工作了(虽然我可能在某个地方犯了错误,因为我是通过内存写的),依赖关系正在解决,并且正确的控制器每次都使用正确的依赖关系进行实例化,但似乎每个请求正在配置容器以解析当时需要的依赖项.所以我的问题是:

  • 这不是多余的吗?
  • 不应该在Global.asax中完成容器的配置,所以它只进行一次?如果是这样,怎么办呢?
  • 通过按照我的方式配置容器,对象生命周期将如何受到影响?我的意思是,最终会有应该具有单例生存期的存储库,其他一些应该通过HTTP请求创建一次,因此也是如此.可能是什么影响?

任何评论,想法和/或建议将不胜感激.

顺便说一句,我正在使用的IoC容器是StructureMap,虽然我认为对于这个特定的问题,它可能不太相关.

Mar*_*ann 3

事实上,根据请求有条件地注册每个控制器是多余的。使用 StructureMap,控制器工厂应该如下所示:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

所有服务都应无条件注册在单个容器实例中。例如,您可以像这样使用 StructureMap 注册所有控制器:

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

这基本上只是遵循Register Resolve Release 模式