15

私はIoC、依存性注入などを学び、そのプロセスを楽しんでいます。インタフェースへのデカップリングとプログラミングのメリットは、私にとっては納得のいくことです。IoCフレームワーク実装をデカップリングする方法

しかし、UnityやAutofac、Windsorなどの特定のフレームワークに自分自身をバインドすることは本当に好きではありません。私はまだ学習しており、どちらが自分の目的に最も適しているかを決めていないからです。

私はどのようにUnityのようなものを包み込むことができるので、後でWindsorで簡単に交換できますか? (または何でも)。あなたは最初のものを注入するために別のものを使うと言うのを敢えてしないでください)

ありがとう!

R.

p.s.私はそれが私の現在の個人的な好み(私はちょうどEntlibに恵まれている)としてUnityにタグ付けしました。

答えて

18

​​をResolveRegisterとして宣言することで、コンテナから抽象化を試みることができます。私はそれを数回しました。次に、コンテナIContainerを実装し、抽象的に実際のIoCコンテナをカプセル化します。私はUnityとCastle Windsorでそれを試しました。

しかし、ちょっと、私はすぐに、これは実際にはオーバーエンジニアリングであることに気付きました。私は、抽象化から抽象化しようとしたが、別の抽象化を構築しようとしていることを理解した。これはコンセプトを学ぶにはうまくいくかもしれませんが、実際のプロジェクトでは首に本当の痛みがありました。私はIoCコンテナからの抽象化に対して強く勧めます。 DI原則を正しく使用すると、とにかに容器を交換するのがかなり簡単になります。

コードはAyendeによって参照this post

//I did this mess with Service Locator 
var t = ContainerService.Instance.Resolve<IMyType>(); 
//others could go further with same Service Locator 
var t = IoCFactory.Instance.CurrentContainer.Resolve<IMyType>(); 

//better way, use --> IoC and DI <-- 
//when a program starts, or a new instance of the context created 
var t = Container.Resolve<IMyType>() //this lives at the bottom of the stack 
//and then you just pass IMyType to the constructor of other types  
//you don't need to call Resolve again in the logical cycle 

のように、overcomplicatedに見えます。

はい、Inversion of Control Containerを抽象化しました。私はあなたがそれをする必要があるならば、それはかなり明らかですあなたは本当にIoCがすべてであるものを得ることはありません。

+0

良い点、過剰設計のようなIoCの抽象化 – pkmiec

+0

あなたは正しく、これは要件を学習するためのものです。いったん私が自分のコンテナに入れたら、私は満足しています。しかし、ブログ上の例がyではなくxを使用しているので、あなたが学習していて別のコンテナを調達するためにアプリケーションを書き直さなければならないときは、しばらくしてからあなたに届きます。私は自分の例を持ち、特定のコンセプトを説明するためにブログがどのコンテナを使っていたとしても簡単に交換できる方法を見つけ出すことはいいと思っていました。 – Richard

+0

私は同意する、これは過剰です。まともなIoCコンテナには、コンテナへの参照でコードを汚染する必要がないように、設定の余地が十分にあるはずです。コンテナを抽象化することが有効になる唯一の方法であれば、あなたはIoCコンテナを使用していないと言いたいでしょう。 – FMM

3

Common Service Locatorライブラリをご覧ください。

+6

imho、CSLは実際には、異なるIoCライブラリを使用する複数の異なるプロジェクト間で使用されるコンポーネントを構築する場合にのみ有効です。たとえば、単一の基幹業務アプリケーションでCSLを使用することは、過度の作業です。それは、依存関係管理に多くを追加し、アプリケーション自体のコアインフラストラクチャに固有のものと同じように、非常に狭いインターフェースしか提供しません。 –

+3

CSLのデザイナーの一人として、私は上記のコメントをしっかりと支持しています。 CSLは、コンテナを必要としているが、ライブラリ上のコンテナの選択をアプリケーションに強制したくないライブラリ作成者を対象としています。 –

18

コンストラクタインジェクションを使用して、クラスが必要とする依存関係を伝達します。リストしたすべてのコンテナがサポートしています。

コードによっては完全なコンテナの独立性を達成できないことがありますが、これらのケースはコードベースのごく一部である必要があります。

+5

コンストラクタインジェクションを好むことは絶対に正しいです。 – FMM

4

他の人々が述べたように、コンストラクタインジェクションを好む。これはあなたの問題の多くを解決します。

クラスがIoCコンテナ自体に直接依存する場合は、サービスロケータ(アンチ)パターンを使用する方法の変種になりがちです。この特定のケースでは、サービスロケータを介してどのタイプが解決されているかを分離し、ファクトリインターフェイスを使用してその動的解決を抽象化します。だから、例えば、これを置き換えます。これで

public class Foo 
{ 
    private MyIoCContainer _container; 

    public Foo(MyIoCContainer container) 
    { 
     this._container = container; 
    } 


    public void DoSomething() 
    { 
     // have to do this at runtime for whatever reason 
     var myObj = this._container.Resolve<ISomeType>(); 

     myObj.DoSomething(); 
     myObj.DoSomethingElse(); 
    } 
} 

を:

public class Foo 
{ 
    private IObjFactory _provider; 

    public Foo(IObjFactory _provider) 
    { 
     this._provider = provider; 
    } 


    public void DoSomething() 
    { 
     var myObj = _provider.GetObj(); 

     myObj.DoSomething(); 
     myObj.DoSomethingElse(); 
    } 
} 

public interface IObjFactory 
{ 
    ISomeType GetObj(); 
} 

は今、あなたはISomeTypeを実装するオブジェクトを構築する動的な、実行時の自然をカプセル化することができますIObjFactoryを持っています。コンテナ/サービスロケータから多くの異なるタイプのオブジェクトを構築する場合は、少なくとも*Factoryインタフェース(Interface Segregation Principleに従う)が必要です。

9

DI容器は、Composition Rootからのみ参照する必要があります。 他のすべてのモジュールには、コンテナへの参照がありません。あなたはDIコンテナを変更した場合

-markシーマン(Dependency Injection in .NETの作者)つまり

は、あなただけの1つのクラスを変更する必要がなければなりません。

コンストラクタインジェクションは通常、他の人が触れたように、適切な方法です。その場でオブジェクトを作成する必要がある場合は、ファクトリインターフェイスまたはFunc<T>代理人を挿入できます。

可能であれば、XML設定を避けることをおすすめします。

関連する問題