Reputation: 3889
I see in many MVC examples how to register your interfaces in the ConfigurationServices
method of the Startup
Class. This is fine when you have your code all written within the MVC app, but in the 'Real World' this wouldn't necessarily be the case.
I have a class library project in the form
public class MyService : IMyService
{
private readonly IMyRepository _myRepository;
public MyService(IMyRepository myRepository)
{
_myRepository = myRepository;
}
.......
Now in my controller I have a constructor of the form:
public HomeController(IConfigurationRoot config, IMyServcie myService)
{
......
The problem is, the MyService
interfaces have not been registered with the DI Container and I don't really want to bloat the ConfigurationServices
method with loads of services.AddScoped<interface,class>()
lines of code for my other layers.
What do I need to do in my other layers (Repository and Service) to first register them here (both are .NET Core class library projects) and then wire those containers into the parent container?
Upvotes: 2
Views: 194
Reputation: 246998
ConfigurationServices
is your composition root so that's where you register you services. The bloat has to go somewhere. You can create an extension method in your other layers and targets IServiceCollection
and then populate as needed. They technically are not first registered there. they are registered in the composition root when you apply the extension method against IServiceColection
Your other layers would have to reference Microsoft.Extensions.DependencyInjection.Abstractions
in order to have access to the IServiceCollection
interface.
IMO I don't think these extension methods need to be in your service or repository layers. Those layers don't need to know anything about how they are composed. You can just as easily put them in your composition root in another class and call them just as shown above if the end goal is to make the startup class cleaner. Or put in a separate extension project which is specifically for targeting .net core's DI framework.
Service Extension Layer
public static IServiceCollection AddMyServices(this IServiceCollection services) {
services.AddScoped<IMyService, MyService>();
//...add other services
}
Repository Extension Layer
public static IServiceCollection AddMyRepositories(this IServiceCollection services) {
services.AddScoped<IMyRepository, MyRepository >();
//...add other services
}
And then in your composition root ConfigureServices
public void ConfigureServices(IServiceCollection services) {
//...other code
services
.AddMyServices()
.AddMyRepositories();
//...other code
}
UPDATE
based on comment you could just as easily call the services.AddMyRepositories()
in the AddMyServies
extension method as opposed to the main project itself
public static IServiceCollection AddMyServices(this IServiceCollection services) {
services.AddMyRepositories();
services.AddScoped<IMyService, MyService>();
//...add other services
}
And then in your composition root, ConfigureServices
will only need to call the AddMyServices
public void ConfigureServices(IServiceCollection services) {
//...other code
services.AddMyServices();
//...other code
}
Upvotes: 5