AutoFac解析键控注册的界面

时间:2014-12-03 14:44:45

标签: unit-testing autofac

我正在使用AutoFac并在我的注册中使用以下行

两个不同的clases用两个不同的键实现相同的接口..

_builder.RegisterType<CopyAppDataUserBudgetLine>().Keyed<ICopyAppData>(EntityType.UserBudgetLine).As<ICopyAppData>().InstancePerDependency();
_builder.RegisterType<CopyAppDataBudgetLine>().Keyed<ICopyAppData>(EntityType.BudgetLine).As<ICopyAppData>().InstancePerDependency();

同一个类用两个不同的键注册

_builder.RegisterType<RemoveOldAppData>().AsImplementedInterfaces().Keyed<IRemoveOldData>(EntityType.UserBudgetLine).InstancePerDependency();
_builder.RegisterType<RemoveOldAppData>().AsImplementedInterfaces().Keyed<IRemoveOldData>(EntityType.BudgetLine).InstancePerDependency();

班级定义

public class RemoveOldAppData : RemoveAppDataBase, IRemoveOldData
    {
        public RemoveOldAppData(KonstruktEntities context, 
            ISQLQueryWhereClauseHelper sqlQueryWhereClauseHelper,
            IQueryExecutionHelper queryExecutionHelper) : base(context,sqlQueryWhereClauseHelper,queryExecutionHelper) { }
        public void RemoveBudgetLines(EntityType entityType, AccessEngine.LineAccessFilter filter)
        {
           ...
        }
    }

public class CopyAppDataBudgetLine : CopyAppDataBase , ICopyAppData
    {
        public CopyAppDataBudgetLine(KonstruktEntities context,
            ISQLQueryWhereClauseHelper sqlWhereClauseHelper,
            IQueryExecutionHelper queryExecutionHelper,
            ITableColumns columns) : base(context,sqlWhereClauseHelper,queryExecutionHelper,columns) { }

        public void CopyData(string receivingUserId, AccessEngine.LineAccessFilter queryFilter)
        {
            ...
        }
        public EntityType CopyDataEntityType
        {
            get;
            set;
        }
    }

以下是我尝试解决这些问题的方法

using (var scope = _container.BeginLifetimeScope())
{
    var copyAppDataUserBudgetLine = scope.Resolve<ICopyAppData>();
    copyAppDataUserBudgetLine.CopyData("leif.andersson", filterAcccess);

问题:如何解决上述问题以获取特定的EntityType(UserBudgetLine),我是否在类的构造函数中或其他位置使用它?

编辑:我使用以下内容开始工作:

var copyAppDataUserBudgetLine = scope.ResolveKeyed<ICopyAppData>(EntityType.UserBudgetLine);

这是正确的方法,还是应该以不同的方式解决这个问题?

2 个答案:

答案 0 :(得分:0)

这就是我最终要做的事情。这是一种方法,但我希望能够始终使用 scope.Resolve适用于所有类型的接口,并且不会被迫为这些类型的场景执行scope.ResolveKeyed

var copyAppDataUserBudgetLine = scope.ResolveKeyed<ICopyAppData>(EntityType.UserBudgetLine);

答案 1 :(得分:0)

我假设EntityType是你正在键入类的一些枚举?

当我解析键控接口时,我更喜欢使用自定义工厂,它从构造函数中获取来自Autofac的IIndex。

当Autofac将此工厂解析给我时,Autofac将基本上为我提供类型及其键的字典。

我会通过执行类似下面的操作来实现这一点,我从您的示例中伪编码...

public Enum EntityType
{
    UserBudgetLine,
    BudgetLine
}

public class EntityCopyAppDataFactory
{
    private readonly IIndex<EntityType, ICopyAppData> _copyAppDataIndex;

    public EntityCopyAppDataFactory(IIndex<EntityType, ICopyAppData> copyAppDataIndex)
    {
        _copyAppDataIndex = copyAppDataIndex;
    }

    public ICopyAppData GetCopyAppData(EntityType entityType)
    {
        return _copyAppDataIndex[entityType];
    }
}

然后在Autofac中注册此工厂

builder.RegisterType<EntityCopyAppDataFactory>();

然后我会从Autofac请求我的工厂,并使用我需要的EntityType.UserBudgetLine调用GetCopyAppData,或者从下面的范围调用,或者通过我的堆栈顶部的构造函数注入调用。

using (var scope = _container.BeginLifetimeScope())
{
    var myFactory = scope.Resolve<EntityCopyAppDataFactory>();
    var copyAppDataUserBudgetLine = myFactory.GetCopyAppData(EntityType.UserBudgetLine);
}

我希望这给你一些思考另一个方向的食物,而不是叫ResolveKeyed?