如何简化ASP.NET核心依赖项注入

时间:2019-01-12 18:37:43

标签: asp.net-core dependency-injection

由于asp.net核心DI仅提供构造函数注入和方法注入。 如果有很多服务需要注入。 与其在构造函​​数内部写很多东西,而不必经常更改构造函数。 我可以只使用某种提供程序,以便在控制器内的任何地方获得服务吗?

代替:

public class HomeController : BaseController
{
    public HomeController(
        IEmailService emailService,
        ISMSService smsService,
        ILogService logService,
        IProductRepository _productRepository)
        :base(emailService,smsService,logService)
    {
    }
    public IActionResult()
    {
        _emailService.SendSomething();
    }
    ...
}
public class BaseController : Controller
{
    protected readonly IEmailService _emailService;
    protected readonly ISMSService _smsService;
    protected readonly ILogService _logService;
    public BaseController(
        IEmailService emailService,
        ISMSService smsService,
        ILogService logService)
    {
        _emailService = emailService;
        _smsService = smsService;
        _logService = logService;
    }
}

使用某种提供程序,例如:

public class HomeController : BaseController
{

    public HomeController(IDIServiceProvider provider)
        :base(provider)
    {

    }
    public IActionResult()
    {
        _provider.GetScopedService<IEmailService>().SendSomething();
    }
    ...
}
public class BaseController : Controller
{
    protected readonly IDIServiceProvider _provider;
    public BaseController(IDIServiceProvider provider)
    {
         _provider = provider;
    }
}

因此,当BaseController的构造函数发生更改并简化所有控制器的构造函数时,不必每次都更改所有控制器的构造函数。

1 个答案:

答案 0 :(得分:6)

您可以将IServiceProvider注入到控制器中并从中获取依赖关系,但是它不再是DI了,它称为 Service Locator 模式。

public class HomeController
{
    private readonly ITestService _testService;

    public HomeController(IServiceProvider serviceProvider)
    {
        _testService = serviceProvider.GetRequiredService<ITestService>();
    }
}

使用服务定位器是recommended,因为:

1-乍一看,您对控制器的依赖性并不明显。

2-为此很难编写单元测试。

3-现在您的服务还需要一个依赖项(IServiceProvider)。

仅在需要将依赖项注入FilterAttributes或ValidationAttributes时,才使用Service Locator模式。 (您也可以在这种情况下使用ServiceFilter。)