3

プロジェクトでキャッスル ウィンザーを使用しています。一部の登録済みコンポーネントが傍受されました。コンポーネントはインターフェイスを介して登録されるため、Castle Windsor はインターフェイス プロキシを作成します (Castle Windsor はインターフェイスを実装するスタンドアロン型を作成し、コンポジションを使用して実際の実装に委譲します)。残念ながら、プロキシがバイパスされるため、インターフェイスの実際の実装内でメソッドを実行することはできません。

実際の実装内で実際の実装を表すプロキシのインスタンスを取得する方法はありますか?

これが私が達成したいことの例です。Get メソッドを常にインターセプトしたい。これは私の製品コードではなく、デモンストレーション用に考案されたものであるため、このサンプルをリファクタリングする別の方法を提供しないでください。

public interface IProvider
{
    bool IsEmpty { get; }
    object Get();
}

public class ProxyBypassingProvider : IProvider
{
    public bool IsEmpty
    {
        // Calls method directly, not through the proxy.
        get { return Get() == null; }
    }

    public object Get()
    {
        return new Object();
    }
}

public class InterceptedProvider : IProvider
{
    private IProvider _this; // Should hold the proxy instance.

    public bool IsEmpty
    {
        // Calls method through proxy.
        get { return _this.Get() == null; }
    }

    public object Get()
    {
        return new Object();
    }
}

フィールド _this をプロキシのインスタンスに設定するにはどうすればよいですか?

敬具
オリバー・ハナッピ

PS: これは実際の例です。

public interface IPresentationModel
{
    IView View { get; }
}

public interface IView
{
    void SetModel(IPresentationModel model);
}

public PresentationModel : IPresentationModel
{
    public IView View { get; private set; }

    public PresentationModel(IView view)
    {
        View = view;
        View.SetModel(this);
    }
}

一時的なプレゼンテーション モデルを解決しています。一時的なビューが注入されます。ビューはプレゼンテーション モデルについて知る必要があるため、プレゼンテーション モデルは IView.SetModel(this) を呼び出して、そのプレゼンテーション モデルについてビューに知らせます。
問題は、解決された IPresentationModel はプロキシですが、SetModel メソッドは実際の実装しか取得しないことです。したがって、ビューがプレゼンテーション モデルのメソッドを呼び出すとき、インターセプターは起動されません。

これまでに見つけた唯一の解決策は、プレゼンテーション モデルを解決した後に、ビューのプレゼンテーション モデルを手動で設定することです。

var model = _container.Resolve<IPresentationModel>();
model.View.SetModel(model);

私は、この解決策は実際にはあまりうまく解決されていないと思います。

4

1 に答える 1

3

これはいわゆる「これを漏らす」問題であり、インターフェイス プロキシでこれを解決する良い方法はありません。

おそらく、あなたが言及した構成後のステップが最良の解決策になるでしょう。Tuna のOnCreateFacilityを使用できます。これはトランクに組み込まれています。トランクで実行したくない場合は、リポジトリからコードをコピーして v2.0 で使用できます。

于 2009-09-11T15:27:06.050 に答える