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

时间:2016-02-18 18:40:31

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

我有一个使用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静态方法被击中两次,所以我的假设是错误的。谁能纠正我在这里做的事情?我想要这个请求范围的原因是因为我正在从数据库中将某些数据加载到我的上下文类中,所以我不希望这对于给定的页面加载多次发生。

提前致谢。

1 个答案:

答案 0 :(得分:5)

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