私はユニティの解決()メソッドにコンストラクタのパラメータを渡すことはできますか?
-
16-09-2019 - |
質問
私は、依存性注入のために、Microsoftのユニティを使用していると私はこのような何かをしたい:
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
両方がIDataContext
パラメータを取るコンストラクタを持っている、と私はUnityが、私はそれを渡すコンテキストでリポジトリを初期化したいです。またIDataContext
は(私はIDataContext
の3つのインスタンスをしたくない)Unityと登録されていないことに注意します。
解決
彼らは、この機能を追加した今日の時点ます:
ここは最新のドロップでいます:
http://unity.codeplex.com/SourceControl/changeset/view/33899 >
ここではそれについての議論ます:
http://unity.codeplex.com/Thread/View.aspx?スレッドID = 66434 の
例:
container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"
他のヒント
<2セント>
あなたが後でよりか、単にコンテキスト未満を必要とするさまざまなサービスを利用する場合は?
コンストラクタパラメータとのIoCに伴う問題は、サービス・インターフェースが定義する契約の一部であるとは対照的に、パラメータは、最終的に、使用される具体的なタイプに関連付けられていることである。
私の提案はあなたにもコンテキストを解決するのどちらかということだろう、と私はUnityは、あなたがそれの3つのインスタンスを構築避けるための方法を持っている必要があり、またはあなたが構築するための方法を持って工場出荷時のサービスを検討すべきであると考えています対象ます。
たとえば、あなたが後で全く従来のデータベースに依存しているが、代わりにテスト用のダミーデータを生成するためにXMLファイルを使用していないリポジトリを構築することを決定した場合は?どのようにそのコンストラクタにXMLコンテンツを供給して行くのでしょうか?
のIoCは、デカップリング・コードの周りに基づいており、具体的な型に引数の種類と意味論で結ぶことによって、あなたは本当に正しくデカップリングを行っていない、依存性はまだあります。
「このコードは限り、それがああ....このインタフェースを実装し、データコンテキストを使用するように、おそらくリポジトリの任意のタイプに話すことができる。」
さて、私は他のIoCコンテナは、このためのサポートを持っていることを知っているし、私も自分の私の最初のバージョンでそれを持っていたが、私の意見では、それは、解像度ステップで属していません。
2セント>
みんなありがとう...鉱山「が存在」することによってポストに似ています。以下を参照してください:
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
_activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
{
new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
});
あなたは、容器内の事前登録されたオブジェクトのインスタンスを取得するためにResolvedParameter
あなたのケースでは、このオブジェクトは名前で登録されている必要があり、かつ同じinsanceのためにあなたは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")));
非常に短い答えは:なし。 Unityは現在、私は見つけることができたことを、定数または注入されないコンストラクタにパラメータを渡す方法はありません。それはそれが欠けている、単一の最大のものだが、私が思う私見それはデザインではなく、省略することです。
ジェフフリッツが指摘したよう、あなたは理論的には、様々なタイプに注入するためにどのコンテキストインスタンスを知っているカスタム寿命マネージャーを作成することもできますが、それは最初にUnityまたはDIを使用しての目的を解決するためになされたようで、ハードコーディングのレベルです場所。
あなたは完全なDIから戻って小さなステップを取ると、自分のデータコンテキストを確立するためのリポジトリの実装が責任を作ることができます。コンテキストのインスタンスは、まだコンテナから解決することができますが、使用するかを決定するためのロジックは、リポジトリの実装に行かなければならないでしょう。それは確かに、のように純粋ではないのですが、それは問題を取り除くでしょう。
あなたが使用できる別の方法として(それは良い習慣であるかどうか、本当に分からない)二つの容器を作成し、それぞれのインスタンスを登録されます:
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
タグあまりにもこれが役に立てば幸い
NotDan、私はあなたがlassevkするコメントであなた自身の質問に答えているかもしれないと思う。
まず、私はUnityが作成するIDataContextのインスタンスのライフサイクルと数を管理するためにLifetimeManagerを使用します。
http://msdn.microsoft.com/en-us/library/cc440953。 ASPXする
それはあなたが必要インスタンス管理を与えるContainerControlledLifetimeManager
オブジェクトのように聞こえます。代わりにそのLifetimeManagerでは、UnityはIDataContext依存性を必要とするすべてのオブジェクトにIDataContextの同じインスタンスを追加する必要があります。