c# - 如何在 ASP.NET Core 中获取没有构造函数注入(inject)的注入(inject)服务的实例?

标签 c# asp.net-core dependency-injection

我有一个三层架构。

我不能使用构造函数注入(inject),我需要访问我的业务代码中的服务,其中我无权访问 HttpContext

例如,在操作方法、过滤器或中间件中,我可以使用以下方式获得服务:

 HttpContext.RequestServices.GetRequiredService<ITranslator>();

但是在我的业务代码中,我无权访问HttpContext

如何获取我的服务实例?

更新:

这是我的业务代码:

public class InvoiceBusiness
{
   // for some reasons, I can't use constructor injection here

   public void CalculateTranslationsInvoice(long customerId) 
   {
       // I need to get an instance of ITranslator here, and a couple of other services. 
       // If this method was in a controller, I could use HttpContext.RequestServices. 
       // But here what should I do?
   }
}

最佳答案

如果您需要访问内层的 HTTP 问题,您应该将其抽象为一个接口(interface)。

假设您需要访问当前用户。通常,您会使用 HttpContext.User。但是你不能在域层访问它。

解决方案是在您的领域层中定义一个接口(interface),该接口(interface)封装了您的ITranslator 实现从HTTP 上下文中实际需要的内容

public interface IUserAccessor {
    ClaimsPrincipal CurrentUser { get; }
}

public class Translator: ITranslator {
    // inject the interface
    private readonly IUserAccessor _userAccessor;
    public Translator(IUserAccessor userAccessor) {
        _userAccessor = userAccessor;   
    }
    // ...
}

尽可能保持此界面的焦点。在这里,我可以使用 ClaimsPrincipal 并依赖于标准库,但如果您不这样做,您可以只提取用户 ID 声明(如果这在您的应用程序中有意义)。

然后在application/HTTP层实现这个接口(interface)。

internal class HttpUserAccessor: IUserAccessor {
    IHttpContextAccessor _httpAccessor;

    public HttpUserAccessor(IHttpContextAccessor httpAccessor) {
        _httpAccessor = httpAccessor;
    }

    public ClaimsPrincipal CurrentUser => _httpAccessor.HttpContext?.User;
}

然后注册这个实现:

services.AddHttpContextAccessor();
services.AddScoped<IUserAccessor, HttpUserAccessor>();

现在您可以在任何层访问 HTTP 关注点,而该层不知道数据的实际来源。

底线是:您不必放弃依赖注入(inject)。您可以在不同层定义和实现接口(interface)。

关于c# - 如何在 ASP.NET Core 中获取没有构造函数注入(inject)的注入(inject)服务的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68608743/

相关文章:

c# - 一系列存储过程(带有连续 token )是否比 Azure DocumentDb 中的单个普通查询慢?

c# - Unity - 通过 XML 的工厂

c# - .net XmlSerialize 抛出 "WriteStartDocument cannot be called on writers created with ConformanceLevel.Fragment"

jquery - 自动完成下拉列表未正确显示

c# - SignalR accessTokenFactory 不将 token 传递给请求查询字符串

oop - 重构 - 打破依赖关系

c# - Azure Functions 模型绑定(bind)

c# - 是否将用户设置存储在 ASP.NET Core Identity AspNetUsers 表中

.net - 如果使用日志门面,在使用 IoC/DI 时是否应该注入(inject)日志基础设施?

c# - 让 Automapper 使用由带有 WebApi 的 Autofac 构建的服务