Reputation: 125
Since asp.net core DI provides only constructor injection and method injection. If there's a lot of services to inject. Instead of writing a lot inside constructor and change constructors frequently. Can I just use some kind of provider so that I can get the services everywhere inside controller?
Instead of :
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;
}
}
With some kind of provider like:
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;
}
}
So that I don't have to change all controller's constructors every time when BaseController's constructor changes and simplify all controller's constructors.
Upvotes: 2
Views: 297
Reputation: 2311
You can inject IServiceProvider to your controller and get your dependencies from that but it's not DI anymore and it's called Service Locator pattern.
public class HomeController
{
private readonly ITestService _testService;
public HomeController(IServiceProvider serviceProvider)
{
_testService = serviceProvider.GetRequiredService<ITestService>();
}
}
It's recommended to not use Service Locator because :
1- Your controller dependencies are not obvious with the first look.
2- It's harder to write unit tests for that.
3- Your service now needs one more dependency (IServiceProvider).
Use Service Locator pattern only when it needed like injecting your dependencies to FilterAttributes or ValidationAttributes. ( You can use ServiceFilter for this situations too. )
Upvotes: 5