我有一个ASP.NET 5 dnxcore解决方案,其中包含一些项目来区分我的逻辑:
现在我使用DI在我的API控制器的构造函数中调用我的服务:
private readonly IMyService _myService;
public Controller(IMyService myservice){ _myService = myService; }
我核心中的服务也通过构造函数注入获取存储库:
private readonly IMyRepository _myRepo;
public MyService(IMyRepository myRepo){ _myRepo = myRepo; }
目前我需要在我的API的启动类中定义我的DI容器以使其工作。
我的问题是,我怎样才能把这座建筑物放在'在我的Core-project中我的服务中的存储库的DI容器。这样,我的API与我的服务使用Entity Framework这一事实松散耦合,因此我可以在不更改API项目的情况下更改为mongodb。
答案 0 :(得分:7)
您可以轻松地将IServiceCollection的扩展方法添加到服务层,并使用它来注册自己的依赖项。 然后在启动时,您只需在服务层上调用该方法,而无需在Web应用程序中引用EntityFramework。
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>();
}
}
}
启动:
using your.service.layer;
public void ConfigureServices(IServiceCollection services)
{
services.AddMyServiceDependencies();
}
现在,您的网络应用只需要引用您的服务图层,而不是直接依赖于EntityFramework。
答案 1 :(得分:6)
我的问题是,如何在我的Core-project中将存储库的DI容器的“构建”放入我的服务中。这样,我的API与我的服务使用Entity Framework这一事实松散耦合,因此我可以在不更改API项目的情况下更改为mongodb。
你可以,但你不应该这样做。
依赖注入是在整个库中创建松散耦合类的实践,可以将它们连接在一起(通常以多种方式)。
但是,每个应用程序都应该有composition root,这是我们放置耦合代码的应用程序中的一个位置。我们作为开发人员的第一直觉是尝试将耦合代码存储到自己的库中,但这是一种你应该抵制的冲动。请参阅composition root reuse。
也就是说,许多DI容器都可以使用 modules 来组织应用程序某些部分的配置。在Autofac中,modules is here的文档。
答案 2 :(得分:0)
See this question,我有同样的问题,因为我的应用程序是数据库不可知的,并且基于请求将需要在面向文档的数据库(noSQL)和transaccional数据库(SQL)之间切换。
答案 3 :(得分:0)
正如NightOwl888所说,你应该在你的应用程序中有一个CompositionRoot,它是设置所有依赖项的地方。 我做的是这样的: 1.创建名为CompositionRoot的核心类库。 2.添加一个类来处理依赖项:
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>();
}
}
然后在MVC项目和Startup.cs中引用您的CompositionRoot
DependencyMapper.SetDependencies(services, Configuration);
就是这样。