10

私は、(すべてが計画どおりに進んだ場合) 一度に数か月実行される Windows サービスを作成しています。サービスの存続期間中、いくつかの WCF サービス (他のローカル アプリと通信するための名前付きパイプ) を維持し、組み込みデータ ストア (RavenDB はおそらく、この質問には多かれ少なかれ関係ありません) を実行し、それを使用します。 SIP サービス (VoIP 機能) を維持するためのサードパーティ ソフトウェア。私が直面している課題のいくつかは、イベントに反応し、これらのイベントが表すものを処理するためにいくつかの新しいビジネス オブジェクトを作成する必要があることを意味します。

今、私は Mark Seemann の本 (少なくともこの議論に関連する部分) を読み、なぜサービスロケーターが悪いのか、なぜコンポジションルート (私の場合はサービスの開始点) でこれを処理することが良いのかを理解しています。一般的な場合。

しかし、私が理解していないのは、これがあらゆる状況にどのように適用できるかということです。アプリケーションの開始時にルート全体を構成できる場合や、フレームワークによる要求ごとに IoC エンジンが使用される MVC のような場合に、どのように完璧になるかがわかります。ただし、長時間実行されるサービスの場合、すべてのオブジェクトを前もって作成することは、最良の場合でも非効率的であり、場合によっては不可能であると思います。必要なすべてのオブジェクトを前もって取得し、人生が進むにつれて新しいオブジェクトを作成する必要がない、重要なサービスを作成できるとは想像できません。

さて、これは私を暗黒面に誘い込み、サービスロケーターのように隠れた依存関係を犠牲にするのに十分ではありません. しかし、ここで何をするのが正しいのでしょうか? 各着信呼び出しに応答して作成する必要がある CallHandlerService がある場合 (たとえば、高価で管理されていないリソースを使用するため)、それを行うにはどうすればよいですか?

コンポジションルート + ほんの少しのサービスロケーター?

最後の部分は深刻ではありませんでしたが、これを適切に解決する方法を知りたいです。

4

2 に答える 2

16

質問を 2 つに分けることができます。

  • スコープの管理方法
    • 考えられるすべての依存関係を事前に作成しないようにする
    • 必要な依存関係のみを作成する
  • 寿命をどう管理するか
    • すでに作成された依存関係への参照を保持する
    • 可能であれば依存関係を再利用する
    • できるだけ早くそれらをクリーンアップします

スコープの管理方法

いくつかの特殊化された抽象ファクトリのインターフェイスまたは実現のいずれかを定義できます。それぞれは、独自の特別な種類の依存関係のみを管理するように制限されます。たとえば、1 つはデータベース関連の依存関係、もう 1 つは SIP 関連です。次に、依存関係ではなく、ファクトリ自体を注入し、それらから依存関係を取得できます。

Service Locator のように聞こえませんか? はい、そうですが、Service Locator ではありません。詳細については、Mark Seemann のブログ: Abstract Factory or Service Locator?を参照してください。.

抽象ファクトリに問題がない場合は、Ninject.Extensions.FactoryIKernelを見て、構成に基づいて自動的に作成します

寿命をどう管理するか

サービスを年中無休で実行する場合、これはより複雑で重要な部分です。ここでは、いくつかの実用的なアドバイスのみを提供できます。

  • このような種類のサービスでは、外部依存側(データベース、サービスなど)での障害は日常的なものであり、例外ではありません。
  • パフォーマンスや再利用を目的としたコードで、依存関係への参照を自分で保持しないでください
  • 複雑なライフタイムを使用しないでください (たとえば、 Ninject の名前付きスコープ)
  • できるだけ早く依存関係をリリースしてください。それらを管理するように Ninject を構成します。
  • 新しいインスタンスを再作成するために、依存関係のタイムアウトについて考えてください
  • 長時間実行されるタスク用である可能性があり、の別のインスタンスを作成しKernel、後でそれらを破棄したことを確認してください
于 2013-05-19T05:18:08.933 に答える
0

私の謙虚な意見では、依存性注入 (一般的にサービスを提供するために使用されます) はやや暗い芸術であり、それを適切に使用する方法とタイミングについての洞察が本当に必要です。

私の経験から、注入された依存関係にバグや例外がある場合にデバッグしてアプリケーションを適用しようとするのは、特に特定のオブジェクトが同じインターフェイスの背後に隠されているいくつかのオブジェクトの 1 つである場合は、せいぜい退屈なプロセスでした。これが、そのインターフェイスを使用するすべてのオブジェクトの単体テストが重要である理由です。なぜなら、同じ入力でどれが失敗するか分からないからです。

依存性注入は、サービスの起動時に呼び出しの種類ごとにハンドラーを作成するために使用するのが最適です。その後、各呼び出しが発生したときに適切にディスパッチします。ただし、各呼び出しを処理するオブジェクトを作成しようとすると、オーバーヘッドと複雑さが増すと思います。

あなたの本能に従って、それを無駄のないものにしてください。

于 2013-05-18T15:18:21.863 に答える