无法解析与KeyFilterAttribute不工作AutoFac键控服务(Unable to re

2019-09-26 00:33发布

我有一个通用的UnitOfWork模式实现这些的UnitOfWork对象是依赖于我的服务类。 下面的片段应该帮助读者了解我的代码设置:

IUnitOfWork接口

public interface IUnitOfWork<out TContext> where TContext : IDbContext

的UnitOfWork类

public sealed class UnitOfWork<TContext> : IDisposable, IUnitOfWork<IDbContext> where TContext : IDbContext
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(UnitOfWork<TContext>));

        private readonly IDbContext _dbContext;
        private Dictionary<string, IRepository> _repositories;
        private IDbTransaction Transaction { get; set; }

        public UnitOfWork(IDbContext context)
        {
            _dbContext = context;
        }
    }

容器注册:

builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>));

builder.RegisterType<ReconciliationDbContext>().As<IDbContext>();
builder.RegisterType<GenevaDataDbContext>().As<IDbContext>();
builder.RegisterType<OpenStaarsDbContext>().As<IDbContext>();

builder.RegisterType<UnitOfWork<ReconciliationDbContext>>().Keyed<IUnitOfWork<IDbContext>>(ContextKey.Recon);
builder.RegisterType<UnitOfWork<OpenStaarsDbContext>>().Keyed<IUnitOfWork<IDbContext>>(ContextKey.OpenStaars);

builder.RegisterType<CommentsService>().As<ICommentsService>().WithAttributeFiltering();

的DbContext类:

public class ReconciliationDbContext : BaseDbContext<ReconciliationDbContext>, IDbContext
    {
        private const string DbSchema = "BoxedPosition";

        public ReconciliationDbContext() : base("Reconciliation")
        {

        }
    }

public class OpenStaarsDbContext : BaseDbContext<OpenStaarsDbContext>, IDbContext
    {
        public OpenStaarsDbContext() : base("OpenStaars")
        {

        }
    }

CommentsService类:

public class CommentsService : ICommentsService
    {
        private readonly IUnitOfWork<IDbContext> _reconciliationUoW;

        public CommentsService([KeyFilter(ContextKey.Recon)] IUnitOfWork<IDbContext> reconciliationUoW)
        {
            _reconciliationUoW = reconciliationUoW;
        }
    }

解决ICommentsService:

var commentsService = container.Resolve<ICommentsService>();

现在,当我试图解决ICommentsService类型,实例化的UnitOfWork依赖。 然而,UnitOfWork._dbContext属性值将为OpenStaarsDbContext类型。 这是特别奇怪考虑到我们的注册。

它变成如果我们通过OpenStaarsDbContext后注册GenevaDataDbContext重新整理我们的IDbContext登记的更奇怪。 现在_dbContext计算结果为GenevaDataDbContext实例。

我怎样才能解决这个问题,使CommentsService的reconciliationUoW依赖有ReconciliationDbContext的正确实例?

Answer 1:

这种行为的原因是你注入的事实IDbContext到您UnitOfWork构造函数,而不是TContext -容器会忽略你提供一个泛型参数的类型在你注册,并采取第一IDbContext找到容器-这将是最后注册,不管你会用什么键。

为了使它工作,而不是使用键注册,你可以简单地注入IUnitOfWork<ContextYouNeed>代替IUnitOfWork<IDbContext> -这将简化代码。 首先,你需要解决您UnitOfWork类:

class UnitOfWork<TContext> : IUnitOfWork<TContext> where TContext : IDbContext
{
    private readonly TContext _context;

    public UnitOfWork(TContext context)
    {
        _context = context;
    }
}

在你注册,你并不需要注册工种的具体单位,标准通用的注册就足够了。 但是,你需要注册上下文类型AsSelf一样,所以Autofac会适当注入它为您的工作情况的单位:

builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>));

builder.RegisterType<ReconciliationContext>().As<IContext>().AsSelf();
builder.RegisterType<OpenStaarsContext>().As<IContext>().AsSelf();

后来,在您的服务简单地注入工作的正确单位:

public CommentsService(IUnitOfWork<ReconciliationContext> reconciliationUoW)


文章来源: Unable to resolve AutoFac Keyed service with KeyFilterAttribute not working