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);

今問題はこれです:

リポジトリを作成できる必要があります。汎用リポジトリのタイプに応じて、異なるコンテキストを使用する必要があります。レポが使用しているコンテキストを呼び出し元のコードに知らせたくないので、コンテキストをパラメーターとして使用することはできません。それは UnitOfWork でなければなりません。

しかし、ジェネリック リポジトリはジェネリックであるため、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 に答える