【问题标题】:asp.net core, Ef core : Dynamically map repository and services in run timeasp.net core, Ef core : 在运行时动态映射存储库和服务
【发布时间】:2016-10-25 14:07:02
【问题描述】:

我一直在将我的存储库类映射到它的接口,服务也是如此。在这里我可以手动注册它们。但是我希望我的代码在运行时动态映射它们,这样我就不必在每次创建新的存储库或服务时手动注册它们。我怎样才能做到这一点?

这是我的代码:

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>();
}

【问题讨论】:

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


    【解决方案1】:

    让我把你的问题分成两个问题:

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

    (见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 core 中实现批量注册(基于约定)? (见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);
                }
            } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-19
      • 2015-01-13
      • 2021-05-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多