C# 在Autofac'中获取关闭的实现类型;带参数的s

C# 在Autofac'中获取关闭的实现类型;带参数的s,c#,entity-framework,autofac,C#,Entity Framework,Autofac,我正在尝试注册通用存储库,以使用基于实体自定义属性的特定上下文。下面是我所拥有的 天牛 //data layer foreach (var database in DatabaseManager.Databases) { builder.Register<IDbContext>(c => new CodesObjectContext(database.ConnectionString)) .As<IDbContext>() .

我正在尝试注册通用存储库,以使用基于实体自定义属性的特定上下文。下面是我所拥有的

天牛

//data layer
foreach (var database in DatabaseManager.Databases)
{
    builder.Register<IDbContext>(c => new CodesObjectContext(database.ConnectionString))
        .As<IDbContext>()
        .Named<IDbContext>(database.Alias)
        .InstancePerLifetimeScope();
}

builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>))
    .WithParameter(new ResolvedParameter(
        (pi, ctx) => pi.ParameterType == typeof(IDbContext),
        (pi, ctx) => ctx.ResolveNamed<IDbContext>((
            { Generic Type Of EfRepository}.GetType()
                .GetCustomAttributes(typeof(DatabaseAttribute), true)[0] 
                    as DatabaseAttribute).Name)))
    .InstancePerLifetimeScope();
//数据层
foreach(DatabaseManager.Databases中的var数据库)
{
Register(c=>newcodesObjectContext(database.ConnectionString))
.As()
.Named(database.Alias)
.InstancePerLifetimeScope();
}
建筑商注册通用(类型化(电子存储)).As(类型化(电子存储))
.WithParameter(新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(IDbContext),
(pi,ctx)=>ctx((
{EfRepository的泛型类型}.GetType()
.GetCustomAttributes(typeof(DatabaseAttribute),true)[0]
作为DatabaseAttribute.Name)))
.InstancePerLifetimeScope();

我好像到不了这里,
{Generic Type Of EfRepository}
。我是否可以获得正在注册的eRepository的当前泛型类型?

我使用ParameterInfo中的信息来解决它。以下是我的解决方案:

 //data layer
            foreach (var database in DatabaseManager.Databases)
            {
                builder.Register<IDbContext>(c => new CodesObjectContext(database.ConnectionString))
                    .As<IDbContext>()
                    .Named<IDbContext>(database.Alias)
                    .InstancePerLifetimeScope();
            }

        builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>))
            .WithParameter(new ResolvedParameter(
                   (pi, ctx) => pi.ParameterType == typeof(IDbContext),
                   (pi, ctx) => ctx.ResolveNamed<IDbContext>(
                       (pi.Member.DeclaringType.GetGenericArguments()[0] //get generic type
                       .GetCustomAttributes(typeof(DatabaseAttribute), true)[0] as DatabaseAttribute).Name))) //get attribute database name
       .InstancePerLifetimeScope();
//数据层
foreach(DatabaseManager.Databases中的var数据库)
{
Register(c=>newcodesObjectContext(database.ConnectionString))
.As()
.Named(database.Alias)
.InstancePerLifetimeScope();
}
建筑商注册通用(类型化(电子存储)).As(类型化(电子存储))
.WithParameter(新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(IDbContext),
(pi,ctx)=>ctx(
(pi.Member.DeclaringType.GetGenericArguments()[0]//获取泛型类型
.GetCustomAttributes(typeof(DatabaseAttribute),true)[0]作为DatabaseAttribute.Name))//获取属性数据库名称
.InstancePerLifetimeScope();

您可以使用参数信息的
DeclaringType
访问具体解析类型

builder.RegisterGeneric(typeof(EfRepository<>))
       .As(typeof(IRepository<>))
       .WithParameter(new ResolvedParameter(
               (pi, c) => pi.ParameterType == typeof(IDbContext),
               (pi, c) => c.ResolveNamed<IDbContext>(
                   pi.Member.DeclaringType
                     .GetGenericArguments()[0] 
                     .GetCustomAttributes(typeof(DatabaseAttribute), true)
                     .OfType<DatabaseAttribute>()
                     .First()
                     .Name))) 
       .InstancePerLifetimeScope();

您还可以在自定义
模块上创建添加OnPreparing事件。有关详细信息,请参阅。

每个关闭版本的
eRepository
都将具有相同的
数据库属性
,因此对于每个关闭版本的
eRepository
,这将始终导致相同的
名称。所以我认为你所做的根本不起作用。我的评论并不完全针对这个话题
DbContext
应该在简短的场景中使用:您创建它,使用它,调用
SaveChanges
,然后处理它。在存储库的构造函数中传递DbContextFactory。
builder.RegisterGeneric(typeof(EfRepository<>))
       .As(typeof(IRepository<>))
       .OnPreparing(e => {
           e.Parameters = e.Parameters.Union(
               new[] {
                   new ResolvedParameter(
                       (pi, c) => pi.ParameterType == typeof(IDbContext),
                       (pi, c) => {
                           String databaseName = 
                               pi.Member
                                 .DeclaringType
                                 .GetGenericArguments()[0]              
                                 .GetCustomAttributes(typeof(DatabaseAttribute), true)
                                 .OfType<DatabaseAttribute>()
                                 .FirstOrDefault()
                                 .?Name
                           if (String.IsNullOrEmpty(databaseName)
                           {
                               // TODO
                           }

                           c.ResolveNamed<IDbContext>(databaseName)
                       }
                   )
               });
       })
       .InstancePerLifetimeScope();