【问题标题】:How to get an instance of an injected service without constructor injection in ASP.NET Core?如何在 ASP.NET Core 中获取没有构造函数注入的注入服务的实例?
【发布时间】:2021-10-07 01:09:57
【问题描述】:

我有一个三层架构。

我无法使用构造函数注入,我需要访问我的业务代码中的服务,而我无权访问 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?
   }
}

【问题讨论】:

  • 听起来你在这里做错了什么。你能把你需要这个的地方,以及不允许你使用正常注入的代码贴出来吗?
  • @CamiloTerevinto,更新了问题。
  • "由于某些原因,我不能在这里使用构造函数注入" -> 这对我们来说还不够好。那些原因是什么?为什么你在那个班级也需要CalculateTranslationsInvoice

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


【解决方案1】:

如果您需要访问内层的 HTTP 关注点,您应该将其抽象为一个接口。

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

解决方案是在您的域层中定义一个接口,该接口封装您的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层实现这个接口。

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 关注点,而无需该层知道数据实际来自何处。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多