如何使用DynamicProxy合并多个类的多个接口?

时间:2010-11-18 12:49:49

标签: castle-dynamicproxy

假设我们有一个从ICatBase和ICatExtension派生的接口ICat,如下所示。对于两个不同的接口,可以使用CatBase和CatExtension实现。如何使用Castle的DynamicProxy将它们合并到ICat的实例中?

是否可以创建一个代理,其中ICExExtension由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"; }
   }
}

修改

我一直在尝试使用mixins来完成这项工作,但下面的代码会导致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

谢谢你,Krzysztof!使用以下几行是解决方案。

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实例,而不需要引用特定名称?

1 个答案:

答案 0 :(得分:1)

Mixins是你通常使用的。