StructureMap 和 HTTP 请求范围的服务 - 为什么我的服务在单个作用域中创建两次

本文关键字:服务 创建 作用域 两次 单个 我的 请求 HTTP 范围 StructureMap 为什么 | 更新日期: 2023-09-27 18:35:19

我有一个使用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 };
        }
    }
}

我已经在我的结构图注册表中将其连接起来,如下所示:

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

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

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

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

提前谢谢。

StructureMap 和 HTTP 请求范围的服务 - 为什么我的服务在单个作用域中创建两次

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

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

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

有关生命周期的更多信息,请点击此处。

HttpContextLifecycle 已经过时了,但我不知道它是否会或何时被删除。StructureMap 团队建议不要使用此较旧的 ASP.Net 生命周期。他们在文档中指出,大多数现代 Web 框架为每个请求使用嵌套容器来完成相同的范围。 有关嵌套容器的信息可在此处找到。

我不知道您使用的 ASP.Net MVC版本是否被视为现代Web框架。我怀疑这是因为 ASP.Net Core 1.0 实际上是 ASP.Net 中第一个完全接受使用 DI 的产品。 但是,我将推迟@jeremydmiller这个问题。