1

我正在尝试使用 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 中注册所有这些的任何想法?

4

1 回答 1

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 添加异常。

总是欢迎有关如何使眼睛更干净或更容易的建议:-)

于 2012-04-05T08:10:42.733 回答