4

OK、多分ここにそのような質問がすでにあります、しかし私はそれを見つけませんでした。

問題

多くのエントリポイントを持つ大規模なエンタープライズアプリケーションがあります。アプリには次のような部分が含まれています:

  • サーバ
  • デスクトップクライアント
  • 一部のコンソールユーティリティ
  • .NET API(別のアセンブリ、rootクラスはlikeと呼ばれますMyAppAPI
  • COM API(同じ、個別のアセンブリ。たとえば、VBScriptからAPIにアクセスできます。Set api = CreateObject("MyApp.MyAppAPI")
  • Java API(これも同じ)
  • メッセージングAPI(個別のアセンブリ、メッセージキューを介したレイヤー間の通信に使用)

このアプリでは、DIコンテナとしてUnityを使用しています。サーバー/デスクトップクライアント/コンソールユーティリティなどではすべてがクールです。非常に具体的なエントリポイントがあるため、そこでコンポジションルートオブジェクトを初期化し、オブジェクト/依存関係のツリーを初期化するだけで、すべてが魅力のように機能します。それらの問題は私たちのAPIにあります。

#1

ライブラリ/フレームワークでDIを処理する方法は?

上記のリンクから:

コンポジションルートは、アプリケーションインフラストラクチャコンポーネントです。

アプリケーションのみがコンポジションルートを持つ必要があります。ライブラリとフレームワークはすべきではありません。

ええ、それはかっこいいです、しかし..私は私のAPIでDIを使いたいです、それは巨大です!お互いにどう対処するか?

#2

依存関係があり、できればシングルトンにする必要があります(たとえば、作成されたオブジェクトの存続期間を制御する一部のファクトリ)。しかし、APIオブジェクトのインスタンスをいくつか作成することはできますが、このシングルトンインスタンスをそれらの間で共有するにはどうすればよいでしょうか。さらに、同じドメイン内に.NETAPIオブジェクトのインスタンスとCOMAPIオブジェクトのインスタンスを作成できます(必要に応じて、可能な場合はコメントで説明できます)。

私が今持っているもの

私が言ったように、アプリには問題はありません。問題はライブラリ(API)に存在します。だから、私が今持っているもの

  • 授業があるShellBase
  • このクラスには、静的フィールド_Shellsとパブリック静的メソッドが含まれGetRelease
  • コンテナ間には階層があります(たとえば、APIのコンテナはMessagingAPIから継承され、ServerおよびDesktopClientコンテナは.NET APIコンテナから継承されます)。
  • 誰かが(Getメソッドを介して)新しいシェルを要求すると、ShellBaseそのようなコンテナ(またはサブクラスのスーパーコンテナ)がすでに存在するかどうかを確認し、そのインスタンスを返します。または新しいものを作成します

私はこの方法が好きではありませんが、これは私が今想像できる最高のものです。

考えられる解決策

のようなものAPIFactoryを作成します。これによりAPIオブジェクトが作成されますが、エンドユーザーには複雑すぎるように見えます。ユーザードキュメントに書きたくありません。「最初にAPIFactoryインスタンスを作成して保持してから、このファクトリを使用してAPIインスタンスを作成できます」。それは醜いです。私たちのユーザーはただ書くべきvar api = new API()であり、それを使うべきです。

それで、みんな、あなたはどう思いますか?

4

1 に答える 1

0

1:インターフェイスを介して独自の DI コンテナー抽象化を導入する他のフレームワーク/ライブラリを見てきました。次に、DI コンテナーを参照する必要がある場合は常に、このインターフェイスを内部的に使用します。アダプターは、ライブラリーを特定の DI コンテナーに接続するために使用されます。たとえば、Davy Brion の Agatha プロジェクトには、https ://github.com/davybrion/Agatha/blob/master/Agatha.Common/InversionOfControl/IContainer.cs というコンテナー インターフェイスがあり、最もよく使用される DI コンテナー用のアダプターを提供しています。

2:ここであなたの問題を完全に理解しているとは言えませんが、すべてではないにしても、ほとんどの DI コンテナーはシングルトンの有効期間スコープをサポートしています。つまり、コンテナーは単一のインスタンスしか作成しません。たとえば、ninject では次のようにします。

kernel.Bind<IFoo>()
   .To<Foo>()
   .InSingletonScope();

または、パブリック コンストラクターを回避したい場合は、DI コンテナーを使用しない場合と同様に、クラスの静的シングルトン インスタンスを作成できます。そのインスタンスを返すファクトリ メソッドを使用して、シングルトン インスタンスをコンテナーに登録できます。繰り返しますが、ninject の例:

kernel.Bind<IFoo>()
    .ToMethod(c => Foo.Instance);

上で紹介したインターフェースを考えると、API 間で 1 つのコンテナー インスタンスを共有できるはずです (特定のアプリケーションで複数の API を使用する場合)。これにより、シングルトン要件が適用されます。

これが問題でない場合は、2 番目の問題について詳しく説明できます。

于 2012-08-14T07:00:21.393 に答える