私はC#クラスのlibaryをいくつか書きますが、私はクラスに依存性注入を提供するためにNinjectを使いたいと思います。クラスlibaryがロードされるたびに実行されるコード(メソッド)をクラスlibaryが宣言することは可能ですか? Ninjectのバインディングを定義するには、これが必要です。アセンブリ後に実行されるC#メソッドがロードされる
答えて
私は過去9ヶ月間にかなりの量のNinjectを使用しています。あなたがする必要があるようなサウンドは、バインディングを登録するためにあなたのライブラリにあるモジュールをNinjectカーネルに「ロード」することです。
Ninject 1.xまたは2.0ベータ版を使用しているかどうかはわかりません。 2つのバージョンは、概念が少し異なりますが、概念は同じです。私はこの議論のためにバージョン1.xに固執するでしょう。私が知らない他の情報は、あなたのメインプログラムがNinjectカーネルをインスタンス化していて、あなたのライブラリが単にそのカーネルにバインディングを追加している場合、またはあなた自身のライブラリにカーネルとバインディングが含まれている場合です。私はあなたのライブラリ内のバインディングをメインアセンブリの既存のNinjectカーネルに追加する必要があると仮定しています。最後に、このライブラリを動的にロードしており、メインプログラムに静的にリンクされていないことを前提にします。
最初に行うことは、すべてのバインディングを登録するライブラリにninjectモジュールを定義することです。すでにこれを行っているかもしれませんが、言及する価値はあります。例:
public class MyLibraryModule : StandardModule {
public override void Load() {
Bind<IMyService>()
.To<ServiceImpl>();
// ... more bindings ...
}
}
バインドがNinjectモジュールに含まれているので、アセンブリをロードするときに簡単に登録できます。アセンブリをロードしたら、StandardModuleから派生したすべての型をスキャンできます。これらのタイプがあれば、それらをカーネルにロードすることができます。
// Somewhere, you define the kernel...
var kernel = new StandardKernel();
// ... then elsewhere, load your library and load the modules in it ...
var myLib = Assembly.Load("MyLibrary");
var stdModuleTypes = myLib
.GetExportedTypes()
.Where(t => typeof(StandardModule).IsAssignableFrom(t));
foreach (Type type in stdModuleTypes) {
kernel.Load((StandardModule)Activator.CreateInstance(type));
}
上記のコードをさらに一般化して、複数のライブラリを読み込んで複数のタイプを登録することができます。また、前述のように、Ninject 2には、この種の機能が組み込まれています。実際には、ディレクトリのスキャン、アセンブリのロード、モジュールの登録が可能です。とてもかっこいい。
シナリオが私が概説したものと少し異なる場合、同様の原則が適用される可能性があります。
C++のDllMainに相当するものを探しているようですね。 C#でこれを行う方法はありません。
あなたのシナリオに関する詳細とDllMainスタイル関数で実行するコードが必要な理由を教えてください。
タイプに静的コンストラクタを定義しても、この問題は解決されません。静的型コンストラクタは、型自体が使用される前に実行されることが保証されています。静的コンストラクタを定義し、その型にアクセスしないDll内の他のコードを使用することができます。コンストラクタは決して実行されません。
私の知る限り、答えは ではありません。あなたのクラスライブラリにIoCコンテナを設定したいと思うのですが、そのような場合はそうするのは良い考えではありません。あなたのバインディングをどのような依存関係注入の使用ですか?私たちは依存性注入を使用して実行時に依存性を注入し、異なるシナリオで異なるオブジェクトを注入することができます.IoCコンテナを構成する最も良い場所はアプリケーションの起動です(IoCコンテナはアプリケーションのバックボーンのようなものです:))しかし、アプリケーションを起動する責任があるブートストラップに配置する必要があります。単純なアプリケーションでは、Mainメソッドにすることができます。
クライアントコードを制御できますか?はいの場合、アセンブリをロードするときに魔法を行おうとするのではなく、バインディングを行うRegistryのような単一クラスを実装し、IRegistryインターフェイスを実装します。ロード中にアセンブリ内でIRegistryの実装を探し、必要なメソッドを起動できます。
また、あなたのクラスの属性を持つことができます。これらの属性の
[Component(Implements=typeof(IMyDependency)]
外観と、クライアント側のコンテナにそれらをロードします。
または、この種の状況のライブラリであるMEFをご覧ください。
AppDomain.AssemblyLoad
イベントを試しましたか?アセンブリがロードされた後で起動します。
AppDomain.CurrentDomain.AssemblyLoad += (s, e) =>
{
Assembly justLoaded = e.LoadedAssembly;
// ... etc.
};
- 1. メソッドが実行された後にループプログラムが再度実行される
- 2. C#SplashScreenアセンブリがロードされました
- 3. イメージがロードされているメソッドを実行し
- 4. アプリケーション終了後にJNIメソッドが実行される
- 5. 外部スクリプトがロードされた後にVueコンポーネントのメソッドを実行します。
- 6. ページがロードされた後でJavascriptを実行する
- 7. プロパティ取得メソッドが実行されたときにコンストラクタが実行される
- 8. ロードされたアセンブリをC#のRoslyn Workspaceにフィードするには
- 9. メソッドが実行され
- 10. winformが表示された後にイベントを実行するC#
- 11. サーブレットが呼び出されるとすぐにメソッド/イベントを実行する方法/ページがロードされる
- 12. データがロードされる前にマウントされたメソッドが起動される - VueJS
- 13. .NETアセンブリ内のC#スケジュールされたタスクに帰属するメソッド
- 14. コンピュータクラッシュ後VS 2013で 'Antlr3.Runtime'アセンブリがロードされない
- 15. メソッド呼び出し後にRubyコードが実行されない
- 16. メソッドの後に実行されているRubyメソッドが定義されています
- 17. アセンブリが実行されているIDを変更する
- 18. ViewGroup.addView()の実行後に実行されるメソッドはありますか?
- 19. ページが完全にAngularJSでロードされた後に関数を実行する
- 20. Mathjaxが完全にロードされた後にアクションを実行する方法は?
- 21. 角度スクリプトが実行されますページのロード後(解雇)
- 22. モジュールがロードされた後のPythonスタートアップコードの実行
- 23. ページがロードされるときに角ボタン機能が実行されます
- 24. 呼び出されたメソッドの前に実行されるトースト
- 25. デバッグ動的にロードされたアセンブリ
- 26. ウェブページ全体がロードされた後にスクリプトを実行する方法
- 27. 毎回のページがロードされた後にjavascriptを実行する
- 28. アンドロイド:UIが完全にロードされた後のアクションを実行する方法
- 29. ページパーツがjqueryでロードされた後にphpを実行する際の問題
- 30. DOMがAngular Jsでロードされた後にJqueryを実行する方法
クラスライブラリでバインディングを定義したい状況がたくさんあります。異なるライブラリ内の同じサービスの異なる実装を潜在的に持つことができます。どちらも、サービスが使用されるコンテキストに基づいて、同じアプリケーション内で同時に関連する可能性があります。 Ninject(他のIoCと同じように)は、コンテキストバインディングを定義する機能を提供しているため、いくつかの提供されたコンテキストに基づいて異なるコンクリートサービスを起動することができます。 –