asp.net 5 dependency injection in multiple projects

As NightOwl888 have said, you should have a CompositionRoot in your application, the place where all your dependencies are set. What I did is this: 1. Create a Core Class Library named CompositionRoot. 2. Add a class to handle your dependencies:

public class DependencyMapper
{
    public static void SetDependencies(IServiceCollection serviceCollection, IConfigurationRoot configuration)
    {
        serviceCollection.AddEntityFramework()
                         .AddDbContext<SonoPeopleContext>(options =>
                                                        options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"])
                                                        );            

        MapperConfiguration mapperConfiguration = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new AutoMapperProfileConfiguration());
        });
        serviceCollection.AddSingleton<IMapper>(sp => mapperConfiguration.CreateMapper());

        serviceCollection.AddScoped<IUserService, UserService>();

    }
}

Then you reference your CompositionRoot in your MVC project and in your Startup.cs you just do

DependencyMapper.SetDependencies(services, Configuration); 

That's all.


You can easily add an extension method of IServiceCollection into your services layer and use it to register its own dependencies. Then in the startup you just call the method on the service layer without having any reference to EntityFramework in your web app.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace your.service.layer
{
    public static class MyServiceCollectionExtensions
    {
        public static IServiceCollection AddMyServiceDependencies(this IServiceCollection services)
        {
            services.AddScoped<My.Data.Tier.DbContext, My.Data.Tier.DbContext>();
        }
    }

}

Startup:

using your.service.layer;

public void ConfigureServices(IServiceCollection services)
{
    services.AddMyServiceDependencies();
}

Now your web app only needs a reference to your service layer and it is not directly dependent on EntityFramework.


My question is, how can I put the 'building' of the DI container of the repositories in my services in my Core-project. This way, my API is loosely coupled of the fact that my services use Entity Framework, so I can change to, for example, mongodb without changing my API project.

You could, but you shouldn't do that.

Dependency Injection is the practice of making loosely-coupled classes throughout the libraries that can be plugged together (often in many ways).

However, each application should have a composition root, which is the one place in the application where we put the coupling code. Our first instinct as developers is to try to farm the coupling code off into its own library, but that is an urge that you should resist. See composition root reuse.

Mark Seeman's illustration sums it up well. Avoiding transitive dependencies is what is desired when using DI in order to flatten the dependency graph. This ensures assemblies can be used/tested in isolation without dragging along unnecessary dependencies, which in turn makes maintenance easier.

That said, many DI containers have a way to organize the configuration of certain parts of the application by using modules. In Autofac, the documentation for modules is here.