Enterprise Library Unity と他の IoC コンテナー (Windsor、Spring.Net、Autofac など) を使用することの長所と短所は何ですか?
8 に答える
ユーザーグループ向けのプレゼンテーションを準備しています。そのため、私はそれらの束を通過しました。具体的には、AutoFac、MEF、Ninject、Spring.Net、StructureMap、Unity、Windsor です。
私は 90% のケース (コンストラクター インジェクション、主に人々が IOC を使用するもの) を見せびらかしたかったのです。 ここでソリューションを確認できます(VS2008)
そのため、いくつかの重要な違いがあります。
- 初期化
- オブジェクト検索
それぞれに他の機能もあります (AOP やより優れたギズモを備えているものもありますが、一般的に IOC に必要なのは、オブジェクトを作成して取得することだけです)。
注: CommonServiceLocator: http://www.codeplex.com/CommonServiceLocatorを使用して、さまざまなライブラリ オブジェクト取得の違いを無効にすることができます。
残りは初期化で、コードまたは XML 構成 (app.config/web.config/custom.config) の 2 つの方法で行われます。両方をサポートするものもあれば、1 つだけをサポートするものもあります。注意する必要があるのは、IoC を支援するために属性を使用するものがあります。
したがって、ここに違いの私の評価があります:
ニンジェクト
コードの初期化のみ (属性付き)。ラムダを気に入っていただければ幸いです。初期化コードは次のようになります。
IKernel kernel = new StandardKernel(
new InlineModule(
x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
x => x.Bind<ICustomerService>().To<CustomerService>(),
x => x.Bind<Form1>().ToSelf()
));
ストラクチャーマップ
初期化コードまたは XML または属性。v2.5 も非常にラムダ式です。全体として、これは私のお気に入りの 1 つです。StructureMap が属性を使用する方法に関するいくつかの非常に興味深いアイデア。
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = false;
x.ForRequestedType<ICustomerRepository>()
.TheDefaultIsConcreteType<CustomerRepository>()
.CacheBy(InstanceScope.Singleton);
x.ForRequestedType<ICustomerService>()
.TheDefaultIsConcreteType<CustomerService>()
.CacheBy(InstanceScope.Singleton);
x.ForConcreteType<Form1>();
});
団結
初期化コードと XML。素晴らしいライブラリですが、XML 構成は面倒です。Microsoft やハイウェイ ショップに最適なライブラリです。コードの初期化は簡単です:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
Spring.NET
XMLは、私が知る限り近いものです。しかし、機能に関しては、Spring.Net は太陽の下で IC が実行できるすべてのことを実行します。しかし、単一化する唯一の方法は XML によるものであるため、.net ショップでは一般的に避けられます。ただし、Spring.Net の .net バージョンと Java Spring プロジェクトは類似しているため、多くの .net/Java ショップは Spring.Net を使用しています。
注: Spring.NET CodeConfigの導入により、コードでの構成が可能になりました。
ウィンザー
XML とコード。Spring.Net と同様に、Windsor は、実行したいことは何でも実行します。Windsor は、おそらく最も人気のある IoC コンテナーの 1 つです。
IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");
オートファク
XML とコードの両方を混在させることができます (v1.2 を使用)。素敵なシンプルな IoC ライブラリ。大騒ぎせずに基本を行うようです。コンポーネントのローカルスコープと明確に定義されたライフタイム管理により、ネストされたコンテナーをサポートします。
これを初期化する方法は次のとおりです。
var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
.As<ICustomerRepository>()
.ContainerScoped();
builder.Register<CustomerService>()
.As<ICustomerService>()
.ContainerScoped();
builder.Register<Form1>();
今日選択する必要があるとしたら、おそらく StructureMap を使用するでしょう。C# 3.0 言語機能を最大限にサポートし、初期化の柔軟性が最も高くなります。
注: Chris Brandsma は、元の回答をブログ投稿に変えました。
私が見た限りでは、あちこちにいくつかの実装の詳細があることを除いて、それらはほとんど同じです。Unityが競合他社に対して持つ最大の利点は、Microsoftによって提供されていることです。そこには、OSSを恐れている企業がたくさんあります。
欠点の1つは、それがかなり新しいため、古いプレーヤーがすでに解決しているバグがある可能性があることです。
そうは言っても、これをチェックすることをお勧めします。
古いスレッドですが、これは、UnityvsSpring.netと入力したときにGoogleが最初に表示したものです...
XML構成が気に入らない場合、SpringはCodeConfigを実行します
http://www.springframework.net/codeconfig/doc-latest/reference/html/
また、Springは単なるDIコンテナではありません。ドキュメントの「モジュール」セクションを見ると、DIコンテナはそれが行う膨大なスタックの基盤です。
間違っている場合は訂正してください。ただし、このリンクにリストされているように、Autofac 自体が XML 構成をサポートしていると思います: Autofac XML 構成
注意すべき点: Ninject は、コンテキスト依存性注入をサポートする唯一の IoC コンテナーです (Web サイトによると)。ただし、他の IoC コンテナーの経験がないため、それが当てはまるかどうかはわかりません。
Spring には、パラメーターの名前または位置に基づいて、コンストラクターまたはプロパティにパラメーターを注入できるという 1 つの機能があります。これは、パラメーターまたはプロパティが単純な型 (整数、ブール値など) の場合に非常に便利です。ここの例を参照してください。これが、Spring がコードで構成を実行できないことを本当に補うとは思いません。
ウィンザーもこれを行うことができ、構成ではなくコードで行うことができます。(私が間違っている場合は訂正してください。私はここで聞いたことに従っているだけです)。
Unityがこれを行うことができるかどうか知りたいです。
2 セントを追加するだけで、StructureMap と Unity の両方を試しました。私は、StructureMap の文書化が貧弱/誤解を招き、設定が面倒で、使いにくいことがわかりました。同様に、解決時のコンストラクター引数のオーバーライドなどのシナリオをサポートしていないようです。これは、私にとって重要な使用ポイントでした。そこで私はそれをやめて Unity を使い、約 20 分でやりたいことを実行してもらいました。
私は個人的に Unity を使用していますが、それは Microsoft の製品だからです。私は 1 つの理由で決定を後悔しています: それに対して持っている最大のものは、常に例外をスローする原因となる 1 つの大きな "バグ" を持っています。デバッグ中は例外を無視できます。ただし、例外のスローはコストのかかる操作であるため、実行するとアプリケーションの速度が大幅に低下します。たとえば、現在、Unity の例外によってページのレンダリング時間が4 秒長くなるコードの 1 つの場所で、この例外を「修正」しています。詳細と回避策については、次を参照してください。
Unity が SynchronizationLockException を常にスローしないようにすることはできますか?