我有一个新项目,其中将Windsor容器用于IoC。
这是在安装中执行的简化代码
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()在我看来很奇怪,并且注入的对象也将是单例的。
最佳答案
从下到上:
此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。当然,这可能是数据访问过滤器,将其放在其他对象中可能是合理的。
我回答了你的问题吗?