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
とパブリック静的メソッドが含まれGet
、Release
- コンテナ間には階層があります(たとえば、APIのコンテナはMessagingAPIから継承され、ServerおよびDesktopClientコンテナは.NET APIコンテナから継承されます)。
- 誰かが(
Get
メソッドを介して)新しいシェルを要求すると、ShellBase
そのようなコンテナ(またはサブクラスのスーパーコンテナ)がすでに存在するかどうかを確認し、そのインスタンスを返します。または新しいものを作成します
私はこの方法が好きではありませんが、これは私が今想像できる最高のものです。
考えられる解決策
のようなものAPIFactory
を作成します。これによりAPIオブジェクトが作成されますが、エンドユーザーには複雑すぎるように見えます。ユーザードキュメントに書きたくありません。「最初にAPIFactoryインスタンスを作成して保持してから、このファクトリを使用してAPIインスタンスを作成できます」。それは醜いです。私たちのユーザーはただ書くべきvar api = new API()
であり、それを使うべきです。
それで、みんな、あなたはどう思いますか?