我正在尝试使用Autofac执行以下操作:
我有一个单元UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
IContext contextA { get; set ;}
IContext contextB { get; set ;}
public UnitOfWork(IContext contextA, IContext contextB)
{
this.contextA = contextA;
this.contextB = contextB;
}
public void Save()
{
this.contextA.Save();
this.contextB.Save();
}
...
}
我还有一个泛型类GenericRepo:
public class GenericRepo<T> : IRepo<T>
{
private IContext context;
public GenericRepo(IContext context)
{
this.context = context;
}
}
不输入接口,但它们就在那里。
然后我有这些代表:
public delegate IUnitOfWork IUnitOfWorkFactory();
public delegate IRepo<T> IRepoFactory<T>(IUnitOfWork unitOfWork = null);
现在的问题是:
我需要能够创建存储库。根据通用存储库的类型,它必须使用不同的上下文。我不希望调用代码必须知道repo使用的是什么上下文,所以我不能将上下文用作参数,它必须是UnitOfWork。
但是因为泛型repo是通用的,它不知道从UnitOfWork获取什么上下文,所以它必须通过它的构造函数而不是UnitOfWork来获取上下文。
此外,有时调用代码不关心UnitOfWork(因为它不需要保存),并且在这种情况下必须动态创建UnitOfWork - 它仍然需要一个来获取其数据
所以我需要这个工作:
public void TestCode(IRepoFactory<TypeA> repoFacA, IRepoFactory<TypeB> repoFacB, IUnitOfWorkFactory uowFactory)
{
IRepo<TypeA> repoA = repoFacA(); //repoA has contextA from a new UnitOfWork
IRepo<TypeB> repoB = repoFacB(); //repoB has contextB from a new (different) UnitOfWork
IUnitOfWork uow = uowFactory();
IRepo<TypeA> repoA_2 = repoFacA(uow); //repoA_2 has contextA from uow
IRepo<TypeB> repoB_2 = repoFacB(uow); //repoB_2 has contextB from uow
}
换句话说,我需要能够使用参数调用泛型委托,并且根据类型,它需要使用该参数的属性构造一个类。
它还需要在没有参数的情况下工作,在这种情况下,Autofac必须解析并使用参数本身。
有关如何在AutoFac中注册所有这些内容的想法吗?
答案 0 :(得分:2)
好的,我自己找到了。
这是我注册代表的方式:
builder.Register((b, p) => new GenericRepo<TypeA>(((((p.First() as ConstantParameter)).Value as UnitOfWork) ?? b.Resolve<IUnitOfWork>()).ContextA)).As<IRepo<TypeA>>();
builder.Register((b, p) => new GenericRepo<TypeB>(((((p.First() as ConstantParameter)).Value as UnitOfWork) ?? b.Resolve<IUnitOfWork>()).ContextB)).As<IRepo<TypeB>>();
编辑:
或者更好,以第一种方式以通用方式进行:
builder.RegisterGeneric(typeof(GenericRepository<,>)).WithParameter((pi, icc) => true, (pi, icc) => (((((icc as IInstanceLookup).Parameters.First()) as ConstantParameter).Value as IUnitOfWork) ?? icc.Resolve<IUnitOfWork>()).ContextA).As(typeof(IEntityRepository<,>));
'WithParameter()'的第一个参数必须存在,并且必须返回true。我想如果我想过滤给出的参数,我必须在那里做。
反正。如果您有许多需要ContextA的类型,并且只有一些需要contextB,则可以为A进行通用注册,然后为B添加例外。
关于如何使眼睛更干净或更容易的建议总是受欢迎的: - )