4

ユニティコンテナがあり、を使用RegisterTypeして次のリポジトリと実装者を登録するために使用しContainerControlledLifetimeManagerます。

public interface IPersonRepository
{
  Person GetByID(ObjectSpace objectSpace, int id);
}

ObjectSpaceこのパターンを使用すると、各スレッドが異なるスレッド(DBからオブジェクトをフェッチするためのローカルキャッシュ+メカニズム)を使用しているにもかかわらず、同じリポジトリインスタンスを同時に使用する複数のスレッド(Webアプリ)を持つことができます。作業単位など)。しかし、これは私に「汚い」と感じさせます、そして良い種類ではありません:-)

私が本当に欲しいのは:

public interface IPersonRepository
{
  Person GetByID(int id);
}

これを実現するには、子コンテナを作成し、を使用RegisterInstanceして登録する必要がありますObjectSpace。これは、私が次のいずれかである限り、正常に機能します。

  1. IPersonRepository代わりに子コンテナに登録してください
  2. ライフタイムマネージャーをに変更しますTransientLifetimeManager

私もやりたくない。(1)手間がかかりすぎるので、親コンテナに一度登録して、それ以上は登録したくない。(2)は機能しますが、依存関係がたくさんある場合は、これらすべても一時的なものである必要があり、これにより、personリポジトリが必要になるたびに多くのインスタンスが作成されます。

だから私の質問は:親に型を登録する方法はありますが、コンテナの有効期間インスタンスを解決して、親コンテナではなく子コンテナに保存する方法はありますか?たぶん、カスタムライフタイムマネージャーなどを使用する方法はありますか?

私が達成したいのはこれです:

UnityContainer unityContainer = new UnityContainer();
//Might be a custom manager or something
unityContainer.RegisterType<IPersonRepository, PersonRepository>
  (new ContainerControlledLifetimeManager()); 
using (var childContainer = unityContainer.CreateChildContainer())
{
    childContainer.RegisterInstance<ObjectSpace>(new MyObjectSpace());
    //01 Resolves a new instance inside the child container
    var repository = childContainer.Resolve<IPersonRepository>();
    //02 resolves same instance as 01
    repository = childContainer.Resolve<IPersonRepository>();
}

using (var childContainer = unityContainer.CreateChildContainer())
{
    childContainer.RegisterInstance<ObjectSpace>(new MyObjectSpace());
    //03 Resolves a new instance inside the child container
    var repository = childContainer.Resolve<IPersonRepository>();
    //04 resolves same instance as 03
    repository = childContainer.Resolve<IPersonRepository>(); //Resolves the same instance
}
4

1 に答える 1

1

HierarchicalLifetimeManagerUnityに新規追加された質問をするので、これはタイプを登録するときに使用する必要があります。

于 2016-01-18T20:30:13.817 に答える