asp.net核心,Ef核心:在運行時動態映射存儲庫和服務

asp.net-core asp.net-core-mvc c# dependency-injection entity-framework-core

我一直在將我的存儲庫類映射到它的接口,同樣也用於服務。在這裡我可以手動註冊它們。但我希望我的代碼在運行時動態映射這些代碼,這樣我就不必在每次創建新的存儲庫或服務時手動註冊它們。我怎樣才能做到這一點?

這是我的代碼:

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依賴注入通用接口

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核心中實現批量註冊(基於約定)? (參見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);
            }
        } 


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow