【问题标题】:Castle DynamicProxy DefaultProxyBuilder.CreateClassProxyType does not work with proxy generatorsCastle DynamicProxy DefaultProxyBuilder.CreateClassProxyType 不适用于代理生成器
【发布时间】:2014-03-22 00:17:56
【问题描述】:

我正在尝试使用 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));

为什么这不起作用?

【问题讨论】:

    标签: c# castle-dynamicproxy


    【解决方案1】:

    您正在从Activator 创建示例对象;由于您没有使用 Castle-DynamicProxy 库来创建代理,因此 mixin 属性无法正常工作,因为 mixin 背后的接线是通过 intereceptor 完成的。

    您可以简单地先通过 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();
    

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

    允许我们定义类型所需参数的给定和接口:

    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();
    }
    

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

    【讨论】:

    • 感谢@samy 的回复。如果您阅读了我的问题,我已经说过 ProxyGenerator 可以工作,但是当我尝试使用 IoC 时几乎没有用处。我已经解决了这个问题。这个周末我会试着回圈发布答案。
    • @PhillipScottGivens 我解释了为什么Activator-created 对象在答案的第一部分没有实现 ICustomTypeDescription,但我不明白为什么 ProxyGenerator 选项会成为 IOC 的问题
    • 请提供一些使用 IoC 容器的解决方案示例代码,您不知道将传递给构造函数的内容。
    • @PhillipScottGivens 我编辑了我的答案; object 数组的使用是否符合您对基于 IoC 构造代理对象的想法?
    • 我觉得我们在兜圈子。我在您的示例中没有看到 IoC 代码。我正在使用 Autofac,也许您可​​以演示 autofac 如何使用您的方法解析构造函数参数。 @samy
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 2020-08-23
    相关资源
    最近更新 更多