asp.net 5 多个项目中的依赖注入

asp.net 5 dependency injection in multiple projects

我有一个 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 的启动 class 中定义我的 DI 容器以使其工作。

我的问题是,如何将存储库的 DI 容器的 'building' 放入我的核心项目的服务中。这样,我的 API 与我的服务使用 Entity Framework 的事实松散耦合,因此我可以更改为 mongodb 而无需更改我的 API 项目。

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.

你可以,但你不应该那样做。

依赖注入是使 loosely-coupled 类 整个库可以插入在一起的做法(通常以多种方式)。

但是,每个应用程序都应该有一个 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总结的很好。在使用 DI 以展平依赖关系图时,避免传递依赖关系是 所期望的。这确保程序集可以 used/tested 隔离,而不会拖延不必要的依赖关系,这反过来又使维护更容易。

也就是说,许多 DI 容器都可以通过使用 模块 来组织应用程序某些部分的配置。在 Autofac 中,modules is here.

的文档

您可以轻松地将 IServiceCollection 的扩展方法添加到您的服务层,并使用它来注册自己的依赖项。 然后在启动时,您只需调用服务层上的方法,而无需在您的网络应用程序中引用 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();
}

现在您的 Web 应用程序只需要引用您的服务层,而不是直接依赖于 EntityFramework。

,我遇到了同样的问题,因为我的应用程序与数据库无关,并且根据请求需要在面向文档的数据库(无SQL)和事务数据库(SQL).

正如 NightOwl888 所说,您的应用程序中应该有一个 CompositionRoot,这是设置所有依赖项的地方。 我所做的是: 1. 创建一个名为 CompositionRoot 的核心 Class 库。 2.添加一个class来处理你的依赖:

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 项目中引用你的 CompositionRoot,在你的 Startup.cs 中你只是做

DependencyMapper.SetDependencies(services, Configuration); 

就这些了。