首页 > 解决方案 > 是否可以为整个执行路径提供特定于请求的类?

问题描述

考虑以下 ASP.NET Core 项目/类结构:

Request comes in   
  Middleware
    Controller [calls]
      BusinessLayer
        BusinessRules  
          HelperClasses
            DomainSpecificClass
                etc..

当请求进来时,我想在中间件组件中设置一些值,并让它们在 DomainSpecificClass 中可用 - 对于该特定请求。我想,我可以通过依赖注入和方法参数的组合来探测这些值,但我想知道是否有更简单的方法。

就像是:

// middleware class
public async Task Invoke(HttpContext context) {
   // RequestContext is a made up class
   RequestContext.Referrer = context.Request.Headers["Referer"].ToString();
}

// DomainSpecificClass
private void DoStuff() {
   string referrer = RequestContext.Referrer;
}

这种类型的实现在 .NET Core 中是否可行?

标签: c#.netasp.net-core.net-core

解决方案


您可以创建一个从“当前”请求中提供所需数据的类,并将其在 DI 中注册为“Scoped”——每个请求一个实例。

public interface ICurrentRequest
{
    string Referrer();
}

public class CurrentRequest : ICurrentRequest
{
    private readonly IHttpContextAccessor _contextAccessor;

    public CurrentRequest(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public string Referrer()
    {
        return _contextAccessor.HttpContext.Request.Headers["Referer"].ToString();
    }
}

使用 ASP.NET 内置 DI 容器将实现注册为“Scoped”

services.AddHttpContextAccessor(); // Built-in extension method
services.AddScoped<ICurrentRequest, CurrentRequest>();

在业务层消费

public class DomainSpecificClass
{
    private readonly ICurrentRequest _currentRequest;

    public DomainSpecificClass(ICurrentRequest currentRequest)
    {
        _currentRequest = currentRequest;
    }

    private void DoStuff() 
    {
        var referrer = _currentRequest.Referrer();
    }
}

ICurrentRequest抽象可以在业务层中声明,因此应用程序的任何主机都可以实现它,并且业务逻辑将不依赖于“Http”抽象。


推荐阅读