基本的なDI / IOCの質問 - アーキテクチャ、SimpleInjector
-
21-12-2019 - |
質問
次のようなアーキテクチャに関してIOCコンテナを設定するときに単純なハングアップがあります。
私のアプリケーションでは、このようなレイヤーがあります(下から上へ):
- project.domain
- Project.Web (System.Web.HTTPなど)といくつかのコアHTTPタイプのロジック)
- このプロジェクトでは BaseController があります。
- Project.microservices Web API 2.2にGet / Postなどを実装する。これらはProject.WebのBaseControllerから継承し、参照Project.domain
- project.logging ロギング をクロスカットしようとしています
マイクロサービス層のコントローラが要求されたとき(GET、POSTなど)SimpleInjectorはプロパティインジェクションを使用してiLoggerのインスタンスをBaseControllerに追加します。したがって、MicroServicesプロジェクトのコントローラはすべてアクセスできます。これはこれまでにうまく機能します。
これが私の問題です:
ドメイン層であっても、クロスカットルールを破壊し、物事を切り離すことなく、アーキテクチャ全体にアクセスできるようにしたいと思います。私のアイデアは、ロギングレイヤが購読できるドメイン層から公開されたイベントです。しかし、私は掘ります。私が理解していないのは、SimpleInjectorをドメインにロガーインスタンスに渡す方法です(思考?)アプリの起動時、またはWebリクエストでのみ表示されますか。それはシングルトンインスタンス、または一時的なものになるべきですか?そして、これはどのようにしてLog4netに最適です(私のアーキテクチャを過度に複雑にすることが可能です)。
起動時に登録が起こることを実感しますが、インスタンスを取得するのはどうですか?私が理解しているものから、私は自動コンストラクタ注入を使用してcontainer.getInstance()を使用する必要があります。拡張子
また、幾分無関係です。私はlog4netの機能を抽象化していますが、私は最近私がおそらくそうしないことを学びました。このすべてがどのようにしてそれを考慮しているかについての推奨事項が好きです。
解決
あなたの投稿は少し曖昧であり、より多くのコンテキストなしで答えるのは簡単ではない質問に満ちていますが、私は最善を尽くします。
ロギングをアーキテクチャ全体にアクセスできるようにしたい ドメイン層
に
ロギングの明確な抽象化がある場合は、その抽象化をアプリケーションで利用できるようにして、アプリケーションを通してロギングします。
Log4netの機能を抽象化していますが、最近学んだ 私はおそらくそうではないはずです。
私は同意しません。私はあなたがすべきだと思います。可能であれば、ログ記録で、アプリケーションのコアをサードパーティのコンポーネントに依存させるのを防ぎます。それは solid 原理。 依存反転原則、抽象化はクライアントによって定義されます。ロギングフレームワークは必要な抽象化を定義できません。
しかし、説明されているようにロギングのトラップに落ちすぎないようにしてくださいここに。ほとんどの場合、あなたはしばしばそれを記録してはいけません、しかしむしろ速く失敗し、コードベース全体を通してあなたのためのログ記録を行う代わりに、あなたのためのログ記録を行ういくつかの一般的なコードを持っています。
私が理解できないものは、SimpleInjectorをロガーに渡す方法です。 ドメインへのインスタンス(私が思考のなら、考え方?)
これについての意見がたくさんあります。 iとマークSeemann コマンドとイベントを持つ貧血のあるドメインモデル(または、私のコマンドとイベントが私のドメインモデルになると言うことができますか?)他の人は彼らのドメインオブジェクトにもっと多くのビジネスロジックを持っています。これらのオブジェクトは、サービスの場所を介してサービスの場所を介してサービスを要求させることが非常に悪い考え
public class Loan
{
public void PayLoan(LoanPeriod periodToPay, ILoanCalculator calculator)
{
// ...
}
}
.
サービスクラスがあるので(コマンドハンドラ< / a>?)それらのドメインメソッドを呼び出すには、それらのサービスクラスにコンストラクターインジェクションを適用し、ドメインメソッドに依存関係を渡すことができます。
登録は起動時に起こることを実感しますが、どうか インスタンス?
各リクエストの開始時にインスタンス(オブジェクトグラフが構築されています)。
私が理解しているものから、自動コンストラクタ注入を使用する必要があります インスタンスを取得するにはcontainer.getInstance()を使用しないでください
それは正しいです。コンテナから解決される任意のサービスでできるだけコンストラクタ注入を使用してください。
しかし、私の豊富な読書にもかかわらず、私はまだどのようにかなり把握できません Web APIリクエストとSimpleInjectorのWeb APIの外で機能します 拡張子
これを理解しているかどうかはかなりありません。これがWebアプリケーション、Windowsサービス、またはコマンドラインツールであるかどうか、ほとんどすべてのアプリケーションはリクエストベースです。 Webアプリケーションを使用すると、要求はWeb要求としてインターネットから入ってきます。 Windowsサービスを使用すると、定期的にオフになるタイマーがあり、各パルスは新しい要求と見なすことができます(あるいは、上げられたイベントが新しい要求の開始の開始である場合はSQLEDENCEDENCYを使用している)。コンソールアプリケーションは、おそらく単一の要求を持ち、その直後にダイを締めます。 Webアプリケーションの場合、Simple Injectorはいくつかのサービスの有効期間を暗黙的に制御しますが、Windowsサービスとバックグラウンドプロセスはこれを明示的に制御する必要があります。 ライフ
TimesCope と ExecutionContextScope ライフスタイルを許可そのような要求のためにオブジェクトの有効期間を制御する明示的なスコープを定義することができます。ファスクのILogger.Log
は、バックグラウンドでILoanCalculator
を使用し、Web API要求ごとのスコープを開始して終了します。