简单注入器:如何注入HttpContext?

8

我开始使用Simple Injector作为我的DI容器(主要是出于性能原因,如果有建议,请告诉我),但我编写的一些类使用HttpContextBase作为构造函数参数。 目前我已解决该问题,将其从构造函数中移除并创建一个属性,类似于以下内容:

    public HttpContextBase HttpContext
    {
        get
        {
            if (null == _httpContext)
                _httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
            return _httpContext;
        }
        set
        {
            _httpContext = value;
        }
    }

但我不喜欢这个解决方案... 有什么建议吗?

1个回答

25

在任何情况下,您都应该优先使用构造函数注入。这几乎总是可行的。您可以按以下方式注册您的 HttpContextBase

container.Register<HttpContextBase>(() =>
    new HttpContextWrapper(HttpContext.Current), 
    Lifestyle.Scoped);

当调用Verify()时,可能会出现问题,因为在应用程序启动期间HttpContext.Currentnull,而HttpContextWrapper不允许将null传递给构造函数。

始终尝试保持配置可验证, 您可以将该注册更改为以下内容:

container.Register<HttpContextBase>(() =>
{
    var context = HttpContext.Current;
    if (context == null && container.IsVerifying) return new FakeHttpContext();
    return new HttpContextWrapper(context);
},
    Lifestyle.Scoped);

FakeHttpContext 是一个空的 HttpContextBase 实现,用于防止在容器验证时返回 nullFakeHttpContext 就是这样:

public class FakeHttpContext : HttpContextBase { }

请注意,HttpContext是运行时数据,在构建组件时注入运行时数据是一种反模式。不要将HttpContext或任何抽象层注入到您的组件中,而应创建一个特定于应用程序的抽象层,为消费者提供实际所需的内容(例如用户标识或租户ID)。该抽象层的实现可以简单地在内部调用HttpContext.Current,这完全避免了需要注入HttpContext的情况。

你有Api.dll和Domain.dll。在Domain.dll中,有一个Repository需要从http上下文获取令牌来调用某些微服务并将令牌传递给它。你只能从Http上下文中获取令牌。当创建存储库时,你必须在Scope中设置此令牌。应用程序特定的抽象如何帮助解决这个问题? - Artem A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接