StructureMap 和 HTTP 请求范围的服务 - 为什么我的服务在一个范围内创建了两次?

StructureMap and HTTP request-scoped services - why is my service created twice in a single scope?

我有一个使用 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 请求范围是相同的。

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

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

提前致谢。

配置的默认生命周期是瞬态的,因此每个对 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。