Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net 5 dependency injection in multiple projects

I've got an ASP.NET 5 dnxcore solution with some projects to separate my logic:

  • API
  • Core (with services for business logic)
  • DAL (repository interfaces)
  • Entity Framework (the repositories implementations)

Now I use DI to call my services in the constructors of my API controllers:

private readonly IMyService _myService;
public Controller(IMyService myservice){ _myService = myService; }

The services in my core get the repository thru constructor injection too:

private readonly IMyRepository _myRepo;
public MyService(IMyRepository myRepo){ _myRepo = myRepo; }

Currently I need to define my DI container in the startup class of my API to make it work.

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.

like image 329
Appsum Solutions Avatar asked Jan 24 '16 00:01

Appsum Solutions


2 Answers

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.

like image 137
Joe Audette Avatar answered Oct 03 '22 07:10

Joe Audette


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.

like image 36
IonutC Avatar answered Oct 03 '22 05:10

IonutC