2012-06-21 166 views
4

我正在使用CreateClassProxyWithTarget方法装饰现有对象。但是,构造函数和初始化代码被调用两次。我已经有一个“构造”实例(目标)。我明白为什么发生这种情况,但有没有办法避免它,除了使用空的构造函数?如何避免动态代理:: CreateClassProxyWithTarget代理的双重构造?

编辑:下面是一些代码:

首先创建代理:现在

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

如果我:

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

我用这个例子与下面的类的对象请致电BindingFactory.Create(someKatalogBaseObject);ValuesAttributes 属性再次被初始化。

+0

你能有一些代码,显示你所遇到的问题详细点吗? –

+0

@KrzysztofKoźmic我用一些代码更新了我的问题,它显示了问题。 – Belvasis

回答

0

所以你问的是,如果DynamicProxy可以构造代理实例而不调用它的构造函数?

这是不可能的。有一种方法使用FormatterServices.GetUninitializedObject(),但不适用于中等信任。

+0

没有那不正是我问:-)正如我所说的很清楚,构造函数必须被调用。但是如果我已经有了一个目标,我的理解是,每个呼叫都被转发给目标或由拦截器处理。如果代理在施工期间覆盖目标对象,这是没有意义的。代理对象可以调用构造函数并初始化Values和Attributes属性(参见上面的示例)。但是如果我打电话给proxy.Values,我认为它会简单地转发给target.Values。在这种情况下,代理为自己初始化属性并不重要。 – Belvasis

2

基于关闭的起订量论坛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); 
     } 


    }