【问题标题】:StructureMap and HTTP request-scoped services - why is my service created twice in a single scope?StructureMap 和 HTTP 请求范围的服务 - 为什么我的服务在一个范围内创建了两次?
【发布时间】:2016-02-18 18:40:31
【问题描述】:

我有一个使用 StructureMap 的 ASP.NET MVC 应用程序。

我创建了一个名为 SecurityContext 的服务,它具有静态 Current 属性。简化版如下所示:

public class SecurityContext : ISecurityContext
{
    public bool MyProperty { get; private set; }

    public static SecurityContext Current
    {
        get
        {
            return new SecurityContext() { MyProperty = true };
        }
    }
}

我已将其连接到我的 StructureMap 注册表中,如下所示:

For<ISecurityContext>().Use(() => SecurityContext.Current);

我对Use方法的这个Linq表达式重载的理解是,返回的具体对象对于整个HTTP请求范围都是一样的。

但是,我已经设置了一个测试用例,其中我的上下文接口被注入到两个地方,一次是在控制器的构造函数中,一次是在我的视图继承的基类中使用 SetterProperty 属性。

在调试时,我观察到Current 静态方法被命中两次,很明显我的假设是错误的。谁能纠正我在这里所做的事情?我希望这个请求范围的原因是因为我正在将某些数据从数据库加载到我的上下文类中,所以我不希望在给定页面加载时这种情况发生多次。

提前致谢。

【问题讨论】:

    标签: c# asp.net dependency-injection structuremap


    【解决方案1】:

    配置的默认生命周期是瞬态的,因此对 ISecurityContext 的每个请求都会创建一个新的 SecurityContext 实例。我认为您想要的是使用旧的 HttpContext 生命周期。

    包括 StructureMap.Web nuget 包。然后将您的配置更改为以下内容:

    For<ISecurityContext>()
        .Use(() => SecurityContext.Current)
        .LifeCycleIs<HttpContextLifecycle>();
    

    更多关于生命周期的信息可以在here找到。

    HttpContextLifecycle 已过时,但我不知道是否或何时将其删除。 StructureMap 团队确实建议不要使用这种较旧的 ASP.Net 生命周期。他们在文档中指出,大多数现代 Web 框架对每个请求都使用一个嵌套容器来完成相同的作用域。可以在here 找到有关嵌套容器的信息。

    我不知道您使用的 ASP.Net MVC 版本是否被认为是现代 Web 框架。我怀疑这是因为 ASP.Net Core 1.0 是 ASP.Net 产品线中真正第一个完全接受 DI 的。不过,我会在这件事上听从@jeremydmiller。

    【讨论】:

    • StructureMap 作者(我)的加一
    • 谢谢大家。工作一种享受。我可以问一下,当您说“遗留”时,这是否意味着 HttpContext 生命周期将过时?如果是这样,会用什么代替?
    猜你喜欢
    • 2016-08-03
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 2020-09-24
    • 1970-01-01
    • 2015-08-03
    • 2015-04-14
    相关资源
    最近更新 更多