0

MVP パターンを利用する Windows フォーム アプリケーションがあります。各ビューは WinForms ユーザー コントロールであり、UI 以外の問題を処理するプレゼンターによって支えられています。アプリケーションは Castle Windsor を利用し、すべてのビュー プレゼンターとその他の多くのコンポーネントは Windsor Container を介して解決されます。

私ができるようにしたいのは、ユーザー コントロール ビューのプロパティ インジェクションをカスタマイズすることです。私の見解では、プロパティ インジェクションをあまり活用していませんが、場合によっては非常に便利で、うまく機能します。問題は、ユーザー コントロールにネストされたコントロールが含まれていることが多く、その中に他のネストされたコントロールが含まれている可能性があることです。これらのネストされたコントロールは、コンテナーを介して直接解決されていないため、プロパティ インジェクションは機能しません。

私がやりたいことは、SWFControlクラスから継承するコンポーネントのプロパティ インジェクションを構成することです。コンポーネントのプロパティを見つけることに加えて、ネストされたコントロール (のControls) コレクションのプロパティも検索し、これらのネストされたプロパティにも注入したいと考えています。

Castle Windsor は非常に柔軟で構成可能であることを知っているので、これは可能かもしれません。ただし、正しい方向に少し微調整する必要があります。これは可能ですか?誰かが似たようなことをしようとしましたか?

4

1 に答える 1

1

私があなたの質問を正しく理解していれば、あなたが望むものを達成する唯一の方法は、ある種の貧乏人の依存性注入によるものだと思います(うん、物議を醸しています-私に反対票を投じないでください!)あなたが話しているさまざまなサブコントロールを構築することは、IoCにとって明らかに不利になります。

プロパティ インジェクションを実行できるかどうかはわかりませんが、コンストラクターを利用できます。

まず、windsor コンテナーにアクセスする方法をいくつか作成します。次のような方法でうまくいくでしょう。

public static class MyContainer
{
    private static readonly IWindsorContainer _container = Bootstrap();

    // I did it like this so that there is no explicit dependency
    // on Windsor - this would be the only place you need to change
    // if you want an alternate container (how much you care about
    // that is up to you)
    public static T Resolve<T>()
    {
        return _container.Resolve<T>();
    }

    private static IWindsorContainer Bootstrap()
    {
        var container = new WindsorContainer();
        container.Install(FromAssembly.This());

        // ... whatever else you need to do here

        return container;
    }
}

次に、いくつかのプロパティを注入したい内側のコントロールでは、次のようにします (注入したいものの例として、古き良き ILogger を使用しました)。

public partial class MyFancyControl : UserControl
{    
    // Constructor to keep the winforms designer happy
    public MyFancyControl() 
        : this (MyContainer.Resolve<ILogger>())
    {
        // Intentionally always blank as this 
        // is an un-unit-testable method
    }

    // Constructor that does the actual work
    public MyFancyControl(ILogger logger)
    {
        InitializeComponent();
        Logger = logger;
    }

    public ILogger Logger { get; private set; }
}

注: ロガーを使用すると、いくつかの明白な臭いの 1 つが発生します。そのようなコンポーネントをコンテナーにまったく登録しない場合があります (通常は、null ロガーがあります)。そのため、何らかのメカニズムを接続する必要がある場合があります。それが必要かどうかはあなた次第です。

于 2012-07-04T13:30:05.427 に答える