2012-06-21 167 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); 
     } 


    }