我一直在将我的存储库类映射到其接口(interface),服务也是如此。在这里,我可以手动注册它们。但是我希望我的代码在运行时动态地映射它们,这样我就不必在每次创建新的存储库或服务时都手动注册它们。我该如何实现?

这是我的代码:

public void RegisterDependencies(IServiceCollection services, IConectionSetting connectionSetting)
{
    services.AddDbContext<QuantumDbContext>(options => options.UseSqlServer(connectionSetting.Get()));
    //services.AddDbContext<TestDbContext>(options => options.UseSqlServer(databaseFactory.ConnectionString));
    services.AddTransient<IDatabaseFactory, DatabaseFactory>();
    services.AddTransient<IDbContext, TestDbContext>();
    services.AddTransient<IDbContext, QuantumDbContext>();
    services.AddTransient<IUnitOfWorkManager, UnitOfWorkManager>();
    services.AddTransient<IRepository<CodeTable>, Repository<CodeTable>>();
    services.AddTransient<IRepository<Country>, Repository<Country>>();
    services.AddTransient<IRepository<State>, Repository<State>>();
    services.AddTransient<IRepository<City>, Repository<City>>();

    services.AddTransient<ICodeTableService, CodeTableService>();
    services.AddTransient<ICountryService, CountryService>();
}

最佳答案

让我将您的问题分为两个问题:

1-如何使用内置的DI库在asp.net核心中注册和解析泛型类型?

(请参阅vNext Dependency Injection Generic Interface)

services.AddTransient<IRepository<CodeTable>, Repository<CodeTable>>();
services.AddTransient<IRepository<Country>, Repository<Country>>();
services.AddTransient<IRepository<State>, Repository<State>>();

您可以像这样简单地注册存储库:
services.AddTransient(typeof(IRepository<>), typeof(Repository<>));

2-如何在带有内置DI库的asp.net核心中实现批量注册(基于 session )? (请参阅Convention based binding in ASP.NET 5 / MVC 6)
services.AddTransient<ICodeTableService, CodeTableService>();
services.AddTransient<ICountryService, CountryService>();

我使用以下代码来实现批量注册,并且可以按预期工作,但是我不确定这是否是好方法(此实现中可能有错误的代码):
        // i assume your service interfaces inherit from IService
        Assembly ass = typeof(ICodeTableService).GetTypeInfo().Assembly;

        // get all concrete types which implements IService
        var allServices = ass.GetTypes().Where(t =>
            t.GetTypeInfo().IsClass &&
            !t.GetTypeInfo().IsAbstract &&
            typeof(IService).IsAssignableFrom(t));

        foreach (var type in allServices)
        {
            var allInterfaces = type.GetInterfaces();
            var mainInterfaces = allInterfaces.Except
                    (allInterfaces.SelectMany(t => t.GetInterfaces()));
            foreach(var itype in mainInterfaces)
            {
                if (allServices.Any(x => !x.Equals(type) && itype.IsAssignableFrom(x)))
                {
                    throw new Exception("The " + itype.Name + " type has more than one implementations, please change your filter");
                }
                services.AddTransient(itype, type);
            }
        }

关于c# - asp.net核心,Ef核心: Dynamically map repository and services in run time,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37988238/

10-13 06:08