【问题标题】:How to avoid double construction of proxy with DynamicProxy::CreateClassProxyWithTarget?如何避免使用 DynamicProxy::CreateClassProxyWithTarget 双重构建代理?
【发布时间】:2012-06-21 08:26:13
【问题描述】:

我正在使用CreateClassProxyWithTarget 方法装饰现有对象。但是,构造函数和初始化代码被调用了两次。我已经有一个“构造”实例(目标)。我明白为什么会发生这种情况,但是除了使用空的构造函数之外,还有其他方法可以避免吗?

编辑:这是一些代码:

首先创建代理:

public static T Create<T>(T i_pEntity) where T : class
{
  object pResult = m_pGenerator.CreateClassProxyWithTarget(typeof(T),
                                                           new[] 
                                                             { 
                                                                typeof(IEditableObject),
                                                                typeof(INotifyPropertyChanged) ,
                                                                typeof(IMarkerInterface),
                                                                typeof(IDataErrorInfo)
                                                             },                                                               
                                                           i_pEntity,
                                                           ProxyGenerationOptions.Default,
                                                           new BindingEntityInterceptor<T>(i_pEntity));
  return (T)pResult;
}

例如,我将它与以下类的对象一起使用:

public class KatalogBase : AuditableBaseEntity
{
   public KatalogBase()
   {
     Values     = new HashedSet<Values>();
     Attributes = new HashedSet<Attributes>();
   }
   ...
}

如果我现在打电话给BindingFactory.Create(someKatalogBaseObject); ValuesAttributes 属性正在重新初始化。

【问题讨论】:

  • 你能用一些代码来说明你遇到的问题吗?
  • @KrzysztofKoźmic 我用一些代码更新了我的问题,显示了问题。

标签: c# castle-dynamicproxy dynamic-proxy


【解决方案1】:

根据 Moq 论坛上的 one of Krzysztof's articles 和他的 comment,我已经成功地完成了这项工作:

 class MyProxyGenerator : ProxyGenerator
    {
        public object CreateClassProxyWithoutRunningCtor(Type type, ProxyGenerationOptions pgo, SourcererInterceptor sourcererInterceptor)
        {
            var prxType = this.CreateClassProxyType(type, new Type[] { }, pgo);
            var instance = FormatterServices.GetUninitializedObject(prxType);
            SetInterceptors(instance, new IInterceptor[]{sourcererInterceptor});
            return instance;
        }


        private void SetInterceptors(object proxy, params IInterceptor[] interceptors)
        {
            var field = proxy.GetType().GetField("__interceptors");
            field.SetValue(proxy, interceptors);
        }


    }

【讨论】:

    【解决方案2】:

    那么您要问的是,DynamicProxy 是否可以在不调用其构造函数的情况下构造代理实例?

    那是不可能的。有一种使用 FormatterServices.GetUninitializedObject() 的方法,但在中等信任度下不起作用。

    【讨论】:

    • 不,这不是我要问的 :-) 正如我所说,很明显必须调用构造函数。但是,如果我已经有一个目标,我的理解是,每个呼叫都被转发到目标或由拦截器处理。如果代理在构造期间覆盖目标对象,这没有任何意义。代理对象可以调用构造函数并初始化 Values 和 Attributes 属性(参见上面的示例)。但是,如果我调用 proxy.Values,我认为它会简单地转发到 target.Values。在这种情况下,代理已经为自己初始化了属性并不重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多