简体   繁体   中英

DI in .Net Core MVC 1.0

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?

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM