C# 如何使用autofac动态更改DI?

C# 如何使用autofac动态更改DI?,c#,dependency-injection,autofac,repository-pattern,C#,Dependency Injection,Autofac,Repository Pattern,我们正在开发windows服务,我想在存储库中动态更改dbcontext类 下面是一个场景 我有三个db上下文类 public abstract class Context : DbContext, IUnitOfWork { protected Context(string connectionString) : base(connectionString) { } } public class PlatformCo

我们正在开发windows服务,我想在存储库中动态更改
dbcontext

下面是一个场景

我有三个db上下文类

 public abstract class Context : DbContext, IUnitOfWork
    {
        protected Context(string connectionString) : base(connectionString)
        {

        }
    }

    public class PlatformContext : Context
    {
        private readonly string _connectionString;

        public PlatformContext(string connectionString)
            : base(connectionString)
        {
            _connectionString = connectionString;
        }
    }

    public class PlatformReplicaContext : Context
    {
        private readonly string _connectionString;
        public PlatformReplicaContext(string connectionString)
            : base(connectionString)
        {
            _connectionString = connectionString;
        }
    }

    public class TempContext : Context
    {
         private readonly string _connectionString;
         public TempContext(string connectionString)
        : base(connectionString)
         {
           _connectionString = connectionString;
         }
   }
我有一个存储库

public interface ICategoryRepository : IRepository<Category>
   {

   }

 public class CategoryRepository :Repository<Category>, ICategoryRepository
   {
        public CategoryRepository(Context context) : base(context)
        {

        }
   }
但是当从CQRS打来电话时

var categoty = new Category();
var command = new CategoryBasicQuery {CategoryId = categoryId};
var result =  _mediator.Send(command);
VS给我以下错误

我的autofac注册如下

    builder.RegisterType<CategoryService>().AsSelf();
    builder.RegisterType<ActionRepository>().As<IActionRepository>();
    builder.RegisterType<CategoryRepository>().As<ICategoryRepository>();
    builder.RegisterType<Mapper>().As<IMapper>();
builder.RegisterType().AsSelf();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
有谁能帮我解决这个问题,或者提出处理这种情况的好方法吗


谢谢。

这可能会为您提供一个很好的解决方案起点:

当然,这需要进行调整,以便它能够适应应用程序设计的其余部分。一个可能的例子是:

Context context = this.contexts[action];

using(ILifetimeScope scope = container.BeginLifetimeScope(builder =>
{
    builder.RegisterInstance(context).As<Context>();
}))
{
    // Because we are resolving IMediator from the scope, the selected Context will be used in all dependencies
    var mediator = scope.Resolve<IMediator>();
    mediator.Send(...);
}
Context-Context=this.Context[action];
使用(ILifetimeScope scope=container.BeginLiftimescope)(生成器=>
{
builder.RegisterInstance(context.As();
}))
{
//因为我们正在从作用域解析IMediator,所以所选上下文将在所有依赖项中使用
var mediator=scope.Resolve();
调解人发送(…);
}

顺便说一句,…
DbContext
已经是一个工作单元了,所以
IUnitOfWork
没有添加任何内容。没有明白你的意思吗?1)我不认为从具体的
DbContext
类型创建抽象上下文有什么意义。2)
DbContext
已经是工作单元模式的一个实现,因此
Context
或派生类型不需要这样做,说明
IUnitOfWork
是一种redundant@Roshan-嗯,有几种方法可以做到这一点。问题是-决定使用哪种上下文的条件是什么?解决方案将取决于它。@AlexanderLeonov-我们可以依赖一个变量,比如说有一个叫做action的变量,如果action是使用不同上下文的东西,问题是我无法想象如何集成这个变量。
var categoty = new Category();
var command = new CategoryBasicQuery {CategoryId = categoryId};
var result =  _mediator.Send(command);
    builder.RegisterType<CategoryService>().AsSelf();
    builder.RegisterType<ActionRepository>().As<IActionRepository>();
    builder.RegisterType<CategoryRepository>().As<ICategoryRepository>();
    builder.RegisterType<Mapper>().As<IMapper>();
builder.RegisterType<PlatformContext>().Keyed<Context>("platform");
builder.RegisterType<PlatformReplicaContext>().Keyed<Context>("replica");
builder.RegisterType<TempContext>().Keyed<Context>("temp");
public class Class1
{
    private readonly IIndex<string, Context> contexts;

    public Class1(IIndex<string, Context> contexts)
    {
         this.contexts = contexts;
    }

    public void Whatever()
    {
        string action = ...; // platform, replica or temp
        Context context = this.contexts[action];
        ...
    }
}
Context context = this.contexts[action];

using(ILifetimeScope scope = container.BeginLifetimeScope(builder =>
{
    builder.RegisterInstance(context).As<Context>();
}))
{
    // Because we are resolving IMediator from the scope, the selected Context will be used in all dependencies
    var mediator = scope.Resolve<IMediator>();
    mediator.Send(...);
}