c# - 温莎容器。 ASP.NET MVC 应用程序中对象的生命周期

标签 c# asp.net castle-windsor

我有一个新项目,其中 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 继承的所有类的依赖注入(inject)。

包含 BaseController。

不会对上述以外的其他类进行注入(inject)。

我们向容器表明所有 Controller 类的生命周期都是一个实例。

Component.For<ISecurityManager>().ImplementedBy<SecurityManager>()

对于上面注册的所有 Controller ,如果它们在构造函数接口(interface) ISecurityManager 中将被注入(inject)类 SecurityManager 的实例。

此 SecurityManager 的生命周期默认为单例。因此,在应用程序启动后,我们将只有一个用于所有 Controller 的 SecurityManager 实例,直到应用程序执行结束。

我的想法正确吗?似乎不是,至少因为 Controller 的 LifestyleTransient() 在我看来很奇怪,而且注入(inject)的对象也将是单例。

最佳答案

从下到上:

Lifetime of this SecurityManager is singleton as default value. So after application start we will have only one instance of SecurityManager for all controllers till the end of application execution.

这确实会发生。

It seems that not, at least because LifestyleTransient() for controllers seems to me strange and that injected objects will be singletons too.

Controller 是 transient 的,因为它们持有 HttpContext - 它们具有有关当前用户请求和后续响应的信息。这就是为什么它们是 transient 的而不是单例的——HttpContext 是每个请求的,每次浏览器/客户端请求时都会创建它。

因此 Controller 的生命周期比其他服务短的原因是可以理解的。这在很大程度上取决于应用程序的内部架构。如果其他人知道原因 - 我非常愿意学习。

Controller 的注册/解析/释放周期可以通过创建自定义 Controller 工厂并替换默认值来完成:

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>());

我的 Controller 也有单例依赖。通过这种方式,您可以实现流水线编程模型 - 您通过一系列对象汇集来自 Controller 的请求,然后返回结果。

如果 SecurityManager 与身份验证或授权有关,最好使用 MVC 默认值 Filtering类似 IAuthorizationFilter 的机制或 AuthorizeAttribute .当然,这可能是数据访问过滤器,将它放在不同的对象中可能是合理的。

我回答你的问题了吗?

关于c# - 温莎容器。 ASP.NET MVC 应用程序中对象的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41229975/

相关文章:

c# - 无法使用 Nuget Package Restore 将 Newtonsoft.Json 从 10.0.1 更新到 10.0.2

asp.net - 在 ASP.Net Core Identity 中获取当前主体作为我的自定义应用程序用户

c# - 安全发送/检索数据

c# - 在不创建实现的情况下实现接口(interface)(动态代理?)

c# - 如何获得当前的 CaSTLe Windsor 容器?

c# - 如何在 StructureMap 中使用 InstanceScope.HttpSession?

c# - Windows 中的自动完成文本框和 "Hide Pointer While Typing"

c# - 将两个列表连接在一起

c# - 如何在asp.net中设计多个字段的搜索

c# - CaSTLe Windsor - 删除或更改已注册的实例