93

依存性注入にMicrosoftのUnityを使用していますが、次のようなことをしたいと思います。

IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context

IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);

RepositoryAどちらにもパラメーターRepositoryBを受け取るコンストラクターがあり、IDataContextUnityに渡したコンテキストでリポジトリーを初期化してもらいたいです。IDataContextまた、Unityに登録されていないことに注意してください(3つのインスタンスは必要ありませんIDataContext)。

4

7 に答える 7

72

今日の時点で、彼らはこの機能を追加しました:

ここの最新のドロップにあります:

http://unity.codeplex.com/SourceControl/changeset/view/33899

ここでそれについての議論:

http://unity.codeplex.com/Thread/View.aspx?ThreadId=66434

例:

container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"
于 2009-09-21T23:52:47.660 に答える
39

<2セント>

後で、コンテキストだけでなく多かれ少なかれ必要な別のサービスを使用することにした場合はどうなりますか?

コンストラクターパラメーターとIoCの問題は、サービスインターフェイスが定義するコントラクトの一部ではなく、パラメーターが最終的に使用されている具象型に関連付けられることです。

私の提案は、コンテキストも解決することです。Unityには、コンテキストの3つのインスタンスの構築を回避する方法があるか、オブジェクトを構築する方法のあるファクトリサービスを検討する必要があると思います。

たとえば、後で従来のデータベースにまったく依存せず、代わりにXMLファイルを使用してテスト用のダミーデータを生成するリポジトリを構築することにした場合はどうでしょうか。XMLコンテンツをそのコンストラクターにどのようにフィードしますか?

IoCはデカップリングコードに基づいており、引数のタイプとセマンティクスを具象型に結び付けることにより、実際にはデカップリングが正しく行われていません。依存関係が残っています。

「このコードは、このインターフェースを実装している限り、おそらくあらゆるタイプのリポジトリと通信できます。...ああ、データコンテキストを使用します」。

今、私は他のIoCコンテナーがこれをサポートしていることを知っており、私自身の最初のバージョンでもそれを持っていましたが、私の意見では、それは解決ステップに属していません。

</2セント>

于 2009-04-24T18:48:02.097 に答える
10

ありがとうみんな...私のものは「存在する」による投稿に似ています。下記参照:

        IUnityContainer container = new UnityContainer();
        container.LoadConfiguration();

        _activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
        {
            new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
        });
于 2014-10-29T15:43:22.737 に答える
5

ResolvedParameter <T>( "name")内のインジェクションアーキテクチャに応じて、InjectionConstructor / InjectionProperty / InjectionMethodを使用して、コンテナ内の事前登録されたオブジェクトのインスタンスを取得できます。

あなたの場合、このオブジェクトはNameで登録する必要があり、同じように、LifeTimeManagerとしてContainerControlledLifeTimeManager()が必要です。

_unityContainer.RegisterType<IDataContext,DataContextA>("DataContextA", new ContainerControlledLifeTimeManager());
_unityContainer.RegisterType<IDataContext,DataContextB>("DataContextB");

  var repositoryA = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryB = _unityContainer.Resolve<IRepositoryB>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextB")));
于 2010-04-28T19:02:06.330 に答える
3

非常に短い答えは:いいえ。Unityには現在、定数または注入されていないパラメーターをコンストラクターに渡す方法がありません。これは私が見つけたものです。私見はそれが欠けている唯一の最大のことですが、それは省略ではなく設計によるものだと思います。

Jeff Fritzが指摘しているように、理論的には、さまざまなタイプに注入するコンテキストインスタンスを知っているカスタムライフタイムマネージャーを作成できますが、それは、そもそもUnityまたはDIを使用する目的を取り除くように見えるハードコーディングのレベルです。

完全なDIから少し後退して、リポジトリの実装に独自のデータコンテキストの確立を任せることができます。コンテキストインスタンスは引き続きコンテナから解決できますが、どちらを使用するかを決定するためのロジックは、リポジトリの実装に組み込まれる必要があります。確かにそれほど純粋ではありませんが、問題を取り除くことができます。

于 2009-04-29T12:54:17.740 に答える
1

使用できるもう1つの方法(それが良い習慣かどうかはわかりません)は、2つのコンテナーを作成し、それぞれにインスタンスを登録することです。

IDataContext context = _unityContainer.Resolve<IDataContext>();
_unityContainer.RegisterInstance(context);
var repositoryA = _unityContainer.Resolve<IRepositoryA>(); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(); //Same instance of context


//declare _unityContainer2
IDataContext context2 = _unityContainer2.Resolve<IDataContext>(); //New instance
_unityContainer2.RegisterInstance(context2);
var repositoryA2 = _unityContainer2.Resolve<IRepositoryA>(context2); //will retrieve the other instance

これもお役に立てば幸いです

于 2009-05-15T12:02:27.970 に答える
0

NotDan、lassevkへのコメントであなた自身の質問に答えたかもしれないと思います。

まず、LifetimeManagerを使用して、Unityが作成するIDataContextのライフサイクルとインスタンスの数を管理します。
http://msdn.microsoft.com/en-us/library/cc440953.aspx

ContainerControlledLifetimeManagerオブジェクトが必要なインスタンス管理を提供するようです。そのLifetimeManagerを配置したら、UnityはIDataContextの同じインスタンスをIDataContextの依存関係を必要とするすべてのオブジェクトに追加する必要があります。

于 2009-04-28T10:18:17.360 に答える