Castle DynamicProxy DefaultProxyBuilder.CreateClassProxyType不适用于代理生成器

时间:2014-03-16 20:35:56

标签: c# castle-dynamicproxy

我正在尝试使用mixins创建代理类型。在以下示例中,TypePresenter实现ICustomTypeDescriptor。当我创建一个实例时,“GetProperties”会抛出一个NotImplementedException。

当我使用ProxyGenerator.CreateClassProxy做同样的事情时,一切正常!我希望得到这种类型,以便我可以将它与IoC一起使用。

var options = new ProxyGenerationOptions();
options.AddMixinInstance(new TypePresenter<SampleViewModel>());

var builder = new DefaultProxyBuilder();
var sampleType = builder.CreateClassProxyType(typeof(SampleViewModel), null, options);
var sample = Activator.CreateInstance(sampleType);

var typeDescriptor = (ICustomTypeDescriptor)sample;

// Error happens on this line.
var properties = typeDescriptor.GetProperties();

var property = properties["DoIt"];
Assert.IsNotNull(property);
Assert.IsTrue(property.PropertyType == typeof(ICommand));

为什么这不起作用?

1 个答案:

答案 0 :(得分:0)

您正在从Activator创建示例对象;因为你没有使用Castle-DynamicProxy库来创建代理,所以mixin属性不能工作,因为mixin后面的连接是通过一个interceptor完成的。

您可以先通过ProxyGenerator创建示例,然后将其转换为ICustomTypeDescriptor,您真的不需要它的类型:

var options = new ProxyGenerationOptions();
options.AddMixinInstance(new TypePresenter<SampleViewModel>());

var pg = new ProxyGenerator();
var sample = pg.CreateClassProxy<SampleViewModel>(options); 
// regarding
//var sampleType = sample.GetType();

var typeDescriptor = (ICustomTypeDescriptor)sample;

// Error doesn't happen anymore on this line.
var properties = typeDescriptor.GetProperties();

修改 在不事先知道构造函数的情况下重新构建类型,可以使用CreateClassProxy重载,它将构造函数参数的object []作为参数;

给定和接口,让我们定义一个类型所需的参数:

public interface IGiveConstructorParametersFor<T> {
    object[] Parameters {get;}
}

可以将它注册到一个具体的类(甚至可以根据我们所处的场景解决多个具体类)。然后我们可以使用以下方法构建一个我们事先不知道的类型,我们事先不知道构造函数参数:

public T Proxify<T>(IGiveConstructorParametersFor<T> constructorParametersForT) {
    var options = new ProxyGenerationOptions();
    options.AddMixinInstance(new TypePresenter<T>());

    var pg = new ProxyGenerator();
    var sample = pg.CreateClassProxy(typeof(T),
                                     null,
                                     options,
                                     constructorParametersForT.Parameters);

    var typeDescriptor = (ICustomTypeDescriptor)sample;
    var properties = typeDescriptor.GetProperties();
}

只要任何类型都可以在运行时映射到构造函数参数接口的实现,它就不需要事先知道它