Как упростить внедрение ядра в asp.net - PullRequest
0 голосов
/ 12 января 2019

Поскольку DI ядра asp.net обеспечивает только инжекцию в конструктор и метод. Если есть много услуг для инъекций. Вместо того, чтобы много писать внутри конструктора и часто менять конструкторы. Могу ли я просто использовать какого-либо провайдера, чтобы я мог получать услуги везде внутри контроллера?

Вместо:

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 голосов
/ 12 января 2019

Вы можете внедрить IServiceProvider в свой контроллер и получить от него свои зависимости, но это больше не DI, и он называется Service Locator pattern.

public class HomeController
{
    private readonly ITestService _testService;

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

Это рекомендуется до не использовать сервисный локатор, потому что:

1- Зависимости вашего контроллера не очевидны с первого взгляда.

2 - Для этого сложнее написать модульные тесты.

3 - Вашему сервису теперь нужна еще одна зависимость (IServiceProvider).

Используйте шаблон Service Locator только тогда, когда это необходимо, например, для внедрения ваших зависимостей в FilterAttributes или ValidationAttributes. (Вы можете использовать ServiceFilter и для этой ситуации.)

...