問題タブ [compositionroot]
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.
c# - caliburn.micro、Bootstrapper、CompositionRoot
CompositionRoot とは何かを理解しようとしています。
これまでのところ、それが何であるかについての詳細な説明は見つかりませんでした。何をしてはならないかについての短い声明だけです。
caliburn.micro を活用するときに付属する Bootstrapper は、「CompositionRoot」という意味ですか?
それとも、アセンブリ内にあるものとその依存関係のみを提供できるため、サービスロケーターのアンチパターンに近いですか。
誰かが CompositionRoot の適切な説明を持っている場合は、共有してください。私はすでにploehのブログを知っています。
CompositionRoot がより優れたアーキテクチャにつながる、および/または問題の解決に役立つことがわかった場合でも、その本を購入する意思はあります。しかし、私がそれが何を助けるかを見るのに十分な情報がないことを知っています.
アップデート
すべての ViewModel に EventAggregator が注入される (コンストラクター注入) としましょう。ここで、必要なときにこれらの ViewModel を動的に作成したいと考えています。タイプを事前に (CompositionRoot で) 登録することはできますが、後で依存関係を解決するにはどうすればよいでしょうか? 私が理解している限り、コンテナはコンポジションルートの後に触れるべきではありません。間違いなく、必要になる前にすべてのインスタンスを作成したくありません (アプリケーションの起動が遅くなります)。ここで「登録 - 解決 - 解放」という意味ですか? (そのパターンは ploeh ブログでも作り出されています)
dependency-injection - 分離された階層型アプリケーションでの DI
3 つのレイヤーがあるとします。UI、ビジネス、データ。DIを使用しています。UIからデータレイヤーにアクセスできないようにしたくありません。
問題は、データ層のDI登録についてです。コンポジション ルートは UI にあり、そこでデータを参照したくありません。私はこの答えを見つけました。私が理解しているように、すべてのレイヤーを参照し、それらはレイヤーではなくライブラリであると考える必要があります。このようにして、ビジネスレイヤーがデータレイヤーまたはその他の必要なものを使用するように指定できます。結局のところ、これがDIが存在する理由です。
それは正しいのですが、問題があります。UI でデータ レイヤーを使用しないでください。しかし、ある開発者が誤って UI からデータを参照し、別の開発者がデータ層から何かを UI クラスに直接注入しました。だから彼は、私が望んでいないビジネス層をスキップしました。
このような状況をどのように処理できますか? いくつかの制限を設けたいのですが、一方で DI の柔軟性が必要です。
もちろん、依存関係を登録するためだけに別のライブラリを用意できると考える人もいます。
ここで最も良いパターンは何ですか?
c# - 依存性注入 - コンストラクターではなくコンポジション ルートでイベントをサブスクライブする
DI を実装する場合、Mark Seemann と Misko Hevery は、コンストラクターは単純であるべきであり、依存関係のみを受け取るべきであると述べています。彼らは他に何もすべきではありません。(こことここ)
ただし、渡された依存関係のイベントをサブスクライブしたいことがよくありますが、コンストラクターでこれを行うと、コンストラクターは依存関係を受け取る以上のことを行います。そうしないと、オブジェクトは完全に初期化されません。
では、コンポジション ルートでイベントをサブスクライブする必要があるオブジェクトをインスタンス化し、それらのイベントをフックして、インスタンス化されたオブジェクトを注入するのは正しいでしょうか?
例えば:
とは対照的に:
c# - 構成ルートには単体テストが必要ですか?
私は答えを見つけようとしていましたが、直接議論されていないようです。DI コンテナーを作成し、そこにすべてを登録してから、すべての依存関係を取得する必要な最上位クラスを解決する、アプリケーションのコンポジション ルートがあります。これはすべて内部で行われているため、コンポジション ルートの単体テストが難しくなります。仮想メソッド、保護されたフィールドなどを実行できますが、単体テストを実行できるようにするためだけにそのようなものを導入することはあまり好きではありません。他のクラスはすべてコンストラクター注入を使用するため、大きな問題はありません。問題は、コンポジションのルートをテストすることに意味があるのかということです。いくつかの追加のロジックがありますが、多くはなく、ほとんどの場合、アプリケーションの起動中にエラーが発生します。私が持っているいくつかのコード:
.net - 「main」メソッドには何をコーディングすればよいですか?
おそらくこれは広すぎる質問かもしれませんが、何がベスト プラクティスで、何が「正しい」と考えられるかを聞きたいと思っています。同様のトピックが見つかりませんでした。これはおそらく、一般的で検索が難しいためです。
これはすべて、Windows サービス プロジェクトに別のサービスを追加したときに始まりました。以前は、メイン メソッドはコンポジション ルートと見なされていたものであり、IoC コンテナー登録コード、app.config の読み取りなどは何らかの形でメイン メソッドにありました。そこで必要な依存関係を組み立てた後Resolve
、コンテナーを呼び出して実行することでサービスを作成しました。
を継承する別のクラスを作成したときServiceBase
、複数のサービスが完全に異なる可能性があり、異なる初期化コードが必要になるため、メインをコンポジション ルートとして使用する意味がないことに気付きました。
私が mather で見つけた唯一の啓発的な投稿は、Mark Seemann によるものOnStart
で、彼はが (その特定のケースでは) 集約ルートになると述べています。
一般的に、適切なコンポジション ルートを選択する際の最善のアプローチは何ですか? この Windows サービス シナリオを外れ値と見なし、他のプロジェクト タイプのコンポジション ルートとしてメイン メソッドを残しながら別の方法でコーディングする必要がありますか、それともすべてのコンテキストで有効なより一般的なアプローチがありますか?
おそらく、サービスが非常に異なるセットアップを必要とするという事実は、メインが構成ルートとして再び使用される複数のスタンドアロン プロジェクトにそれらを分離する必要があることを示しているのでしょうか?
通常は .Net を使用しますが、これはおそらく他の多くのプログラミング言語にも当てはまります。
unit-testing - 工場が適切にバインドされているかどうかをテストする方法は?
Ninjectを使用して、次のものがあり、FluentAssertionsを使用してテストしたいと考えています。
工場が実際に適切にバインドされているかどうかをテストする良い方法はありますか?
c# - 1 つのルートの下で多くのシナリオで必要とされるプリミティブな依存関係を処理するための Windsor 拡張ポイントまたは一般的な IoC 手法はありますか?
バックグラウンド
作成される接続文字列に依存するコンポーネントによって実装される多くのサービスがあります-たとえば:
IOracleConnection
接続文字列を使用するには、接続文字列との接続を作成する必要があり、string
依存関係を解決する必要があるため、一般的には最初のコンストラクターを 2 番目のコンストラクターよりも優先します。
MyIImportantController
には の単一のコンストラクターとパラメーターがありますIImportantRepository
。MyIControllerFactory
はコンポジション ルート (ブートストラップはカウントされません) でありIWindsorContainer.Resolve<T>()
、実行時に使用して、ジョブの適切なコントローラーをアクティブ化します。
したがって、ブートストラップ時に全体が次のようになると思います。
そしてこれはリクエスト時に:
動機
現在、あるアプリケーションでは、IOracleConnection
(およびそれを構築する基礎となる文字列) は、次の場合に認識される場合があります。
- アプリケーションが設計されている (テスト用の架空の接続文字列)
- アプリケーションがコンパイルされます (ビルド変数によって完全に決定される接続文字列)
- アプリケーションがデプロイされている (
web.config
変換で設定された接続文字列) - アプリケーションがブートストラップされます (構成ソースで設定された接続文字列は 1 回だけ読み取られます)。
- アプリケーションは特定のタイプのリクエストを処理します (たとえば、「通常」ではなく、「常に」データを表示したい
ProductionDb
) 。 Important
アプリケーションは、接続がパラメーター化されている要求 (のChicagoDb
代わりに で管理する要求NewYorkDb
など)を処理します。- アプリケーションは、セッションまたはユーザーの詳細によって接続が完全に決定される要求を処理します (ユーザーの 10% は存続し
Db1
、残りはDb2
設計上存続します) 。
質問
同じグラフの同じ依存関係のこれらの潜在的な用途をすべて同時に達成するために、DRY に過度に違反することなく保守可能なコードをどのように作成しますか?
winforms - 依存関係が注入されたクラスとコンテナーをアプリケーションのスタートアップ WinForm に渡す
私は、UI、BLL、および DAL の典型的な 3 層に構成された WinForms アプリケーションに取り組んでいます。スタートアップ プロジェクトとして機能する別のプロジェクトを作成しました。すべての依存性注入セットアップを実行する目的で、自家製の依存性注入コンテナーとして機能する別のプロジェクトも作成されました。自家製の依存性注入コンテナはスタートアップ プロジェクトによってインスタンス化され、インスタンス化されたオブジェクトが最初の WinForm に渡されます。
自家製の依存性注入コンテナーの実装を以下に示します。
スタートアップ プロジェクトを以下に示します。
受信側の WinForm は、注入されたオブジェクトを使用して次のようにインスタンス化されます。
WinForm は、次の 2 つのボタン クリック イベントで挿入されたオブジェクトを使用します。
注入されたオブジェクトを 2 つしか渡していないため、これは今のところ問題なく機能します。しかし、オブジェクトの数が 5 つ以上に増えた場合、これは問題になるようです。その後、5 つ以上のパラメーターをスタートアップの WinForm に渡します。個別に注入されたクラスではなく、AppDependencyInjection と呼ばれる自家製の依存性注入コンテナーを WinForm に渡すことにした場合、渡すパラメーターを 1 つだけに制限できます。これを行うと、プレゼンテーション層が自家製の依存性注入プロジェクトに依存するようになり、プレゼンテーション層が BLL と依存性注入プロジェクトの両方に依存するようになります。これは受け入れられますか?アプリケーションで依存性が注入されたクラスの将来の成長に対応するには、他に何ができますか?