2

以下に示すように、ICatBase と ICatExtension から派生したインターフェイス ICat があるとします。CatBase と CatExtension の両方の異なるインターフェイスに対して、実装が利用可能です。Castle の DynamicProxy を使用して、これらを ICat のインスタンスにマージするにはどうすればよいですか?

ICatExtension が CatExtension によって実装され、ICatBase がインターセプターによって「実装」されているプロキシを作成することは可能ですか? これはどのように達成できますか?

public interface ICatBase
{
   string Name { get; set; }
   int Age { get; set; }
}

public interface ICatExtension
{
   string Description { get; }
}

public interface ICat : ICatBase, ICatExtension
{
}

public class CatBase : ICatBase
{
   public string Name { get; set; }
   public int Age { get; set; }
}

public class CatExtension : ICatExtension
{
   public string Description
   {
      get { return "Furry"; }
   }
}

編集

ミックスインを使用してこれを機能させようとしましたが、以下のコードでは NotImplementedException が発生します。

var generator = new ProxyGenerator();
var options = new ProxyGenerationOptions();
options.AddMixinInstance(new CatBase());
options.AddMixinInstance(new CatExtension());
var cat  = generator.CreateInterfaceProxyWithoutTarget<ICat>(options);        
cat.Name = "Joey";

これは DynamicProxy2 エラーです: ターゲットを持たないメソッド 'Void set_Name(System.String)' に指定されたインターセプターはありません。ターゲットなしでメソッドを呼び出す場合、「続行」する実装はなく、実装を模倣するのはインターセプターの責任です (戻り値の設定、引数の出力など)。

呼び出しをインターセプトして正しいインターフェイスにディスパッチするカスタム インターセプターを作成することもできますが、もっと簡単で優れた方法が必要だと思います。私は正しいですか?

編集#2

ありがとう、クシシュトフ!以下の行を使用することが解決策でした。

var generator = new ProxyGenerator();
var options = new ProxyGenerationOptions();
options.AddMixinInstance(new CatBase());
options.AddMixinInstance(new CatExtension());

var cat = (ICat)generator.CreateClassProxyWithTarget(typeof(object), new[] { typeof(ICat)}, new object(), options);

編集#3

最後のステップとして、Windsor コンテナーを構成して、この例からプロキシーを作成しました。これを行うことができた唯一の方法は、「Cat」という名前を指定し、名前を指定してICat後でインターフェースにキャストすることで System.Object のインスタンスを解決することでした。

WindsorContainer container = new WindsorContainer();
container.Register(
    Castle.MicroKernel.Registration.Component.For<object>().
        Named("Cat").
        Proxy.AdditionalInterfaces(typeof (ICat)).
        Proxy.MixIns(new CatBase()).
        Proxy.MixIns(new CatExtension())
    );

var cat = (ICat)container.Resolve(typeof(object), "Cat");

特定の名前を参照せずに、コンテナーに ICat インスタンスを要求できる、よりエレガントな方法はありますか?

4

1 に答える 1

1

ミックスインは、そのために通常使用するものです。

于 2010-11-18T13:04:28.933 に答える