3

私のアプリケーションは、1つ以上の「プラグイン」アセンブリを動的にロードできるモジュラーアーキテクチャを実装しています。各アセンブリには、インターフェイスを実装するクラスが含まれてIPluginおり、ホストアプリがプラグインとの対話に使用するさまざまなメソッドとプロパティを提供します。

このクラスは必然的にプラグイン内の他のクラスに依存し、これらは独自の依存関係を持つ可能性があります。これまで、Castle Windsor(各プラグインにはIWindsorInstaller依存関係を登録する場所が含まれています)を使用してこれらすべてを管理し、コンストラクターを介してDIを実行してきました。欠点は、publicこのアプローチが機能するためにはクラスが必要であるということです。

私は今、これらすべてのクラスを作成してプラグインをロックダウンしたいと思っていますがinternal、おそらくWindsorを使用できないため、依存関係を処理するための最良の方法がわかりません。クラスが独自の依存関係をインスタンス化することを望まないので(緩く結合されていない、テスト容易性の欠如など)、他にどのようなアプローチがありますか?

4

2 に答える 2

3

欠点は、このアプローチを機能させるには、クラスをパブリックにする必要があることです。

本当じゃない。内部のものを登録することはできますが、Castle Windsor (またはその他の DI コンテナー) の自動配線 (自動コンストラクター注入) 機能が失われる可能性があります。これらのタイプを手動で作成するデリゲートを登録することで、内部のものを登録できます。例えば:

container.Register(Component.For<IService>()
    .UsingFactoryMethod(() =>
    {
        var log = container.Resolve<ILogger>();
        return new RealService(log);
    })
    .LifeStyle.Transient);

手動でサービスを作成することnewは最適ではありません。これは、自動配線によりプラグイン アセンブリのコンポジション ルートが最も保守性が高く保たれるためですが、状況に適した代替手段はないと思います。それでも、これは各サービスに独自の依存関係を作成させるよりはましです (貧弱な DI)。

アップデート

私は何かを思い出しました:次のようなジェネリックメソッドを使用して内部型を登録すると、内部型で自動配線を行うことができるはずです:

container.Register(Component.For<IService>()
    .ImplementedBy<RealService());

これが機能するためには、 のコンストラクターRealServiceがパブリックである必要があります (ただし、RealServiceそれ自体は内部にすることができます)。これは、非常に制限の厳しい Silverlight サンドボックスで実行する場合など、部分的な信頼でも機能します (または、少なくとも Simple Injector で機能しますが、Castle でもこれを実行できるはずです)。

于 2012-10-12T21:57:24.847 に答える
0

Ninject を使用する場合、バインディングを構成する各アセンブリにNinjectModuleを追加し、ホスト アプリケーションでモジュールをロードしてバインディングを登録するだけです。

public class ServiceModule : NinjectModule
{
    public override void Load() 
    {
        Bind<IService>().To<RealService>();
    }
}

RealService同じアセンブリ内にあるため、 は内部に留まり、モジュールはそれを見ることができます。

于 2012-10-12T22:38:57.533 に答える