問題タブ [service-locator]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
interface - 依存性注入 - データ転送オブジェクト (DTO) で使用しますか?
以下のコードを考えてみましょう (簡略化されています)。それぞれが独自の特定のインターフェイスを実装する特定の DTO オブジェクトのリストを返すサービス クラスがあります。実際のコードでは、レガシー コードを使用しているため、Dataset を反復処理することによってこれらのデータが取り込まれます。
質問:
DTO を新しくしたり、Service Locator アンチパターンを使用したりせずに、DTO を作成/使用するにはどうすればよいですか? コンポジション ルートで空の DTO オブジェクトを作成し、コンストラクターを介してそれを Service クラスに挿入することは、あまり意味がありません。実際には、リストを作成するときに DTO を一種の一時変数として使用するからです。
コードでは、DTO を新しくする私の例を見ることができます。しかし、これは、最初から DTO にインターフェイスを実装させない場合よりも気分が良くありません。では、インターフェイスを実装すべきではないので、DTO で DI を使用しないでください。
multithreading - WCF サービスで Service Locator を使用する方法
サービス ロケーターを使用して、WCF サービスで使用されるクラスの具体的なインスタンスを保持しています。ServiceLocator を渡すのではなく、すべてのクラスからアクセスできるように静的にすることにしました。サービス ロケーターは、WCF サービスが開始されたときに設定され、いくつかのパラメーターに応じて、さまざまな具象実装が設定されます。
私の問題は、別の呼び出しが完了する前に WCF サービスへの呼び出しが行われた場合、(私が思うに) ServiceLocator に不適切な実装が取り込まれることです。
サービス ロケータをクラスで使用できるようにし、別のスレッドや WCF サービスの呼び出しで再利用しないようにする方法はありますか?
castle-windsor - IOC 用に設計されていないレガシー アプリで Service Locator Antipattern を回避する
IOC の Service Locator はアンチパターンであるとよく読んでいます。
昨年、作業中のアプリケーションに IOC (具体的には Ninject) を導入しました。アプリはレガシーで、非常に大きく、断片化されています。クラスまたはクラスのチェーンを作成する方法はたくさんあります。Web フレームワーク (カスタム) によって作成されるものもあれば、nHibernate によって作成されるものもあります。変なところにたくさん散らかっているだけです。
さまざまなシナリオをどのように処理し、少なくとも ServiceLocatorish ではなく、さまざまな場所でさまざまなカーネルにならないようにするにはどうすればよいでしょうか (シングルトン、HttpRequest、スレッドなどのスコープが重要です)。
編集現在の SL パターンに至った経緯について、もう少し詳しく説明します。
実際には、複数のカーネルは必要ありません。必要なのは 1 つだけです (実際、SL のため、静的なものは 1 つしかありません)。セットアップは次のとおりです。
1) 7 ~ 8 の異なるプロジェクト/アセンブリに Ninject モジュールがあります。アプリ (webapp) が起動すると、アセンブリ スキャンによってモジュールが収集され、カーネルに読み込まれ、Service Locator に配置されます。そのため、すべてがかなり高価です。
2) 構築に適したカスタム UI フレームワークがあります。それぞれがライフサイクルの一部として 1 ~ 10 個のタブ ページを構成する約 120 個のタブ付きフォームを考えてみてください。SL は 5 ~ 6 か所で戦略的に使用されており、純粋な解決として、またはプロパティのインスタンス化後の注入のみを行うことで、これらすべてをカバーしています。
3) UI の下にあるものは、これらのトップ レベルの呼び出しではカバーされません。これらのクラスが IOC を使用したい場合は、独自の戦略を考え出す必要があります。それぞれ独自の小さな世界であるさまざまな小さなフレームワークがあります。
したがって、私が読んだことからそれを行う理想的な方法は、IOCにアクセスする必要があるときはいつでもカーネルを注入することです...まあ、それで問題ありません。SLの使用は最小限に抑えています。
しかし、このカーネルはどこから入手したのでしょうか? どこでも新しいものを構築して登録したくありません。私が使用しているカーネルが、他のすべての人が使用しているのと同じスコープオブジェクトを保持していることを確認し、すべてのモジュール。その時点で、それが何であれ、Service Locator のように見えますよね?
このアプリは巨大で密結合であることにも注意してください。一度のリファクタリングに数か月を費やす余裕はありません。SL は、時間があるときにできる限り IOC に取り組むための良い方法のように思えました。
dependency-injection - Windowsクライアント(WPF)アプリケーションで依存性注入を行う適切な方法
私はWebアプリケーションのIoC/DIに慣れています-主にMVC3でNinjectします。私のコントローラーは私のために作成され、すべての依存関係、サブ依存関係などが入力されています。
ただし、シッククライアントアプリケーションでは状況が異なります。独自のオブジェクトを作成するか、サービスロケータースタイルのアプローチに戻して、依存関係のあるオブジェクトを提供するようにカーネルに依頼する必要があります(おそらく、テスト容易性を考慮して、何らかのインターフェイスを介して)。
ただし、ServiceLocatorがアンチパターンとして説明されている場所をいくつか見ました。
だから私の質問は-シッククライアントアプリでNinjectの恩恵を受けたいのなら、これをすべて手に入れるためのより良い/より適切な方法はありますか?
- 妥当性
- 適切なDI/IoC
- 可能な限り最小のカップリング
ここではMVVMについて話しているだけでなく、ビューモデルをビューに取り込むことに注意してください。これは特に、カーネルからリポジトリタイプのオブジェクトを提供し、そのリポジトリからフェッチされたエンティティに機能を注入する必要があることによってトリガーされます(データはもちろんデータベースから取得されますが、状態に応じてパラメータとしていくつかのオブジェクトも必要です世界の、そしてNinjectはそれを提供する方法を知っています)。リポジトリとエンティティの両方をテスト不可能な混乱として残さずに、どういうわけかこれを行うことができますか?
不明な点がありましたらお知らせください。ありがとう!
7月14日編集
提供された2つの答えはおそらく正しいと確信しています。しかし、私の体のすべての繊維はこの変化と戦っています。知識不足が原因の可能性もありますが、このようなやり方の優雅さを理解するのに苦労している具体的な理由も1つあります。
元の質問ではこれについて十分に説明していませんでしたが、いくつかの(最初は4〜5、おそらくもっと後で)WPFクライアントアプリケーションで使用されるライブラリを作成しているということです。これらのアプリケーションはすべて同じドメインモデルなどで動作するため、すべてを1つのライブラリに保持することがDRYを維持する唯一の方法です。ただし、このシステムの顧客が独自のクライアントを作成する可能性もあります。そして、私は彼らに、話しかけるためのシンプルでクリーンなライブラリを用意してもらいたいと思っています。私は彼らにコンポジションルートでDIを使用するように強制したくありません(彼の本でMark Seemanのような用語を使用しています)-それはMyCrazySystemAdapter()を新しくしてそれを使用するだけの場合と比較して非常に複雑になるためです。
ここで、MyCrazySystemAdapter(ここで人々が私に同意しないことを知っているために選択された名前)は、サブコンポーネントで構成され、DIを使用してまとめられる必要があります。MyCrazySystemAdapter自体を注入する必要はありません。これは、クライアントがシステムと通信するために使用する必要がある唯一のインターフェースです。したがって、クライアントは喜んでそれらの1つを取得する必要があり、DIは舞台裏で魔法のように発生し、オブジェクトはベストプラクティスと原則を使用して多くの異なるオブジェクトで構成されます。
これは物事をやりたいという物議を醸す方法になるだろうと私は理解しています。ただし、このAPIのクライアントになる人も知っています。DIシステムを学習して接続し、アプリケーションのエントリポイント(構成ルート)でオブジェクト構造全体を事前に作成する必要があることがわかった場合、単一のオブジェクトを作成する代わりに、中指とデータベースを直接いじって、想像もできないような方法で物事を台無しにしてください。
TL; DR:適切に構造化されたAPIを提供することは、クライアントにとって非常に面倒です。私のAPIは、DIと適切なプラクティスを使用して舞台裏で構築された単一のオブジェクトを提供する必要があります。現実の世界では、パターンや慣習に忠実であり続けるために、すべてを逆方向に構築したいという願望に勝る場合があります。
architecture - アプリケーション内のロギングをどのように設計すればよいですか?
だから私はこれについて多くの研究をしましたが、「はい、それ」と言った答えは見つかりませんでした. 知識豊富な StackOverflow の皆さんが私を助けてくれることを願っています。
いくつかの異なるシナリオでこの問題に遭遇しました。C# アプリがあり、ログに記録したい重要なものがあるとします。
私が興味を持っているのは、どこlogger
から取得するかです。
私が見ているように、私にはいくつかのオプションがあります。
- コンストラクターで MyClass に注入します。
- グローバルに利用可能なサービス ロケーターを使用して取得します。
- メソッド デコレーターと AOP を使用して、ログを記録します。
これらはどれも素晴らしいオプションのようには見えません。#3 は、メソッド呼び出し、入力パラメーター、および/またはスローされた例外の単純なトレースを行うだけでなく、ビジネス ロジックの途中でログを記録しているため、不可能に見えます。#2、単純に思えますが、単体テストは本当に難しいようです。もちろん、すべてを単体テストしたいと思います。#1 は問題なく動作しますが、ビジネス オブジェクト自体とは関係のないログ オブジェクトですべてのビジネス ロジックがごちゃごちゃになります。
上記のオプションのいずれかについて、代替案や考えはありますか? どうもありがとう!
編集:明確にするために、私はすでにDIの方法を知っており(Unityを使用しています)、優れたロギングフレームワークをすでに知っています(log4netを使用しています)。アプリケーション全体でアーキテクチャの意味でロギングを最もスマートな方法で使用する方法を考えてみてください。
* 編集 *
Mark Seeman の回答を解決策としてマークしました。アプリケーションを調べてみたところ、ロギング呼び出しのほとんどがデコレータと同じことを行っていることがわかりました。つまり、メソッドへのエントリ、スローされた例外をログに記録し、戻り値を終了します。
メソッド内で直接ログを記録する必要がある場合もありました。例は、何も返さないがException をスローしないメソッドで高速に失敗したい場合です。LogProvider
そのような場合、名前付きログ インスタンスを取得する参照 a を保持するシングルトンがあります。コードは次のようになります。
LogProviderFactory にはSetProvider
、シングルトンを交換できるメソッドがあります。したがって、単体テストでは次のことができます。
ロギング デコレータはシングルトンと同じ LogProvider (インジェクションによって取得) を使用するため、ロギングはシステム全体で統一されます。
したがって、最終的な解決策はほとんどがオプション 3 であり、ハイブリッド 2 でした (サービス ロケーター パターンですが、サービスはロケーターに「注入」されます)。
AOP
「アスペクト指向プログラミング」に関する限り、私は言語の限界に少しがっかりしました。AOP が将来のリリースで第一級市民として扱われることを願っています。
- PostSharp を試しましたが、自分のマシンで正しく実行できませんでした。さらに、システムに PostSharp をインストールして使用する必要があるという大きな制限がありました (ソリューションに付属の dll などを呼び出すだけではありません)。
- 私は LinFu を使用し、部分的に機能させることができました。ただし、いくつかの例で爆発しました。新しい 2.0 リリースはほとんど文書化されていないため、それがハードルでした。
- ただし、Unity とのインターフェイス インターセプトは、そのままで問題なく機能するようです。ログに記録したいもののほとんどがインターフェイスを実装するクラスにあったことは幸運でした。
c# - Service Locator アンチパターンを回避するには?
抽象基本クラスから Service Locator を削除しようとしていますが、何に置き換えればよいかわかりません。ここに私が持っているものの疑似例があります:
これに関する問題MySpecialResolver
は、派生クラスのインスタンシエーターが、カーネルが例外をスローしないようにするために必要なバインディングを認識していないことです。
ここからどのタイプを解決しなければならないかわからないため、これは本質的に扱いにくいかもしれません。派生クラスはtypes
パラメーターの作成を担当しますが、どこにもハードコーディングされていません。(型は、派生クラスの構成階層の奥深くにある属性の存在に基づいています。)
遅延読み込みデリゲートでこれを修正しようとしましたが、これまでのところ明確な解決策は思いつきませんでした。
アップデート
ここには実際には 2 つの問題があります。1 つは、IoC コンテナーがコントローラーに渡され、サービス ロケーターとして機能することです。これは簡単に削除できます。あらゆる種類の手法を使用して、コール スタックの上下に位置を移動できます。
2 番目の問題は難しい問題です。要件が実行時まで公開されない場合、コントローラーに必要なサービスがあることをどのように保証できるでしょうか。最初から明らかだったはずです。サービスロケータの状態またはコレクションの内容に常に依存します。この特定のケースでは、静的に型付けされた依存関係に関するこの記事で説明されている問題をいくらいじっても解決しません。私が最終的にやろうとしているのは、Lazy 配列をコントローラー コンストラクターに渡し、必要な依存関係が欠落している場合は例外をスローすることだと思います。
.net - MVC3でNinjectを使用してビュー/ビューモデルにサービスを注入する方法は?
NinjectでMVC3を使用していますが、コントローラーの依存関係は問題なく解決されています。ローカリゼーション、フォーマットプロバイダーなどのサービスがほとんどないので、それらをビューモデルまたはRazorビューに挿入したいと思います。現在、ビューモデルに手動で挿入しています。
- どうすればこれを自動化できますか?
- Razorビューにいくつかのサービスを注入できますか?
- MVCでNinjectを使用してサービスロケーターを設定するにはどうすればよいですか?
その他の場合: Ninjects Bootstrapper.Kernelは廃止され、Service Locatorはアンチパターンであるため、ServiceLocatorは悪い考えのようです。この記事をチェックしてくださいhttp://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
_
c# - XML構成でUnityInjectionFactoryを宣言する方法
Unityの設定をweb.configファイルに移動中です。次のコード構成をxml形式に移行する方法に固執しています。
XML宣言は次のとおりです。
asp.net-mvc-3 - ASP.NET MVC 3 - Common Service Locator を置き換えるときの依存関係リゾルバーの問題
Microsoft Unity を使用して、次のタイプを登録します。
ASP.NET MVC 2 では、次のことができます。
しかし、バージョン 3 では、Service Locator をすべて削除し、代わりに新しい Dependency Resolver を実装しました。したがって、上記を次のように変更しました。
ただし、これは null を返します。
これが役立つ場合の依存関係リゾルバーの実装です。
誰かが私が間違ったことを教えてくれたら本当にありがたいです。ありがとう