我有一个新项目,其中Windsor容器用于IoC。
以下是在Install
中执行的简化代码public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly().BasedOn<BaseController>().LifestyleTransient(),
Component.For<ISecurityManager>().ImplementedBy<SecurityManager>(),
Component.For<IAccountManager>().ImplementedBy<AccountManager>()
........)
}
我在官方文件中找到的信息不足以详细了解这些内容。
Classes.FromThisAssembly().BasedOn<BaseController>().LifestyleTransient(),
Register方法中的这一行启用了从我的应用程序中继承BaseController的所有类的依赖注入。
包含BaseController。
不会对上述其他类别进行注射。
我们向容器展示所有控制器类的生命周期将是一个实例。
Component.For<ISecurityManager>().ImplementedBy<SecurityManager>()
对于上面注册的所有控制器,如果他们在构造函数接口中有ISecurityManager,则会注入SecurityManager类的实例。
此SecurityManager的生命周期是单例作为默认值。因此,在应用程序启动之后,我们将只为所有控制器提供一个SecurityManager实例,直到应用程序执行结束。
我的想法是否正确?似乎不是,至少因为控制器的LifestyleTransient()对我来说似乎很奇怪,注入的对象也会是单身。
答案 0 :(得分:4)
从下到上:
此SecurityManager的生命周期是单例作为默认值。因此,在应用程序启动之后,我们将只为所有控制器提供一个SecurityManager实例,直到应用程序执行结束。
确实会发生这种情况。
似乎不是,至少因为控制器的LifestyleTransient()在我看来很奇怪,注入的对象也会是单身。
控制器是瞬态的,因为它们持有HttpContext - 它们具有有关当前用户请求和以下响应的信息。这就是为什么它们是瞬态而不是单例--HttpContext是每个请求,它是在每次浏览器/客户端请求时创建的。
因此,为什么控制器的寿命比其他服务更短,这是可以理解的。它在很大程度上取决于应用程序的内部架构。如果其他人有更好的想法 - 我非常愿意学习。
控制器的注册/解析/发布周期可以通过创建自定义控制器工厂并替换默认值来完成:
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IKernel _kernel;
public WindsorControllerFactory(IKernel kernel)
{
_kernel = kernel;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
}
if (_kernel.GetHandler(controllerType) != null)
{
return (IController)_kernel.Resolve(controllerType);
}
return base.GetControllerInstance(requestContext, controllerType);
}
public override void ReleaseController(IController controller)
{
_kernel.ReleaseComponent(controller);
}
}
并在某处放置:
container.Register(Component.For<IControllerFactory>().ImplementedBy<WindsorControllerFactory>());
我的控制器也有单例依赖项。通过这种方式,您可以实现管道编程模型 - 您通过一系列对象汇集来自控制器的请求,而不是返回结果。
如果SecurityManager与身份验证或授权有关,最好使用MVC默认Filtering机制,如IAuthorizationFilter或AuthorizeAttribute。当然这可能是数据访问过滤器,将它放在不同的对象中可能是合理的。
我是否回答了你的问题?