我正在构建一个ASP .Net MVC 2应用程序,我想按照Mark Seemann的书“.Net中的依赖注入”中的想法,所以我在Global.asax文件中注册了我的自定义控制器工厂,我正在配置Controller Factory中的容器如下:
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;
}
现在这个代码可以工作(虽然我可能在某个地方犯了错误,因为我是通过内存写的),依赖关系正在被解析,并且正确的控制器每次都使用正确的依赖关系进行实例化,但似乎对于每个请求,容器被配置为解析当时需要的依赖项。所以我的问题是:
非常感谢任何评论,想法和/或建议。
顺便说一句,我正在使用的IoC容器是StructureMap,虽然我认为对于这个特定的问题它可能不太相关。
答案 0 :(得分:4)
确实,根据请求有条件地注册每个控制器是多余的。使用StructureMap,Controller Factory应如下所示:
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);
}
}
所有服务都应无条件地在单个容器实例中注册。例如,您可以使用StructureMap注册所有控制器,如下所示:
this.Scan(x =>
{
x.AssemblyContainingType<HomeController>();
x.AddAllTypesOf<IController>();
x.Include(t => typeof(IController).IsAssignableFrom(t));
});
这基本上只是跟随Register Resolve Release pattern。