I've got an ASP.NET 5 dnxcore solution with some projects to separate my logic:
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With