2011-11-07 40 views
0

我想爲WCF服務創建一個自動生成的代理,它允許我避免手動創建服務代理。Reflection.Emit參數傳遞

使用反射發出,我創建動態類生成的整個週期(從組裝到方法)和我的方法生成的代碼看起來像這樣:

 bool isVoid; 

     if ((isVoid = (methodInfo.ReturnType != typeof(void)))) 
      generator.DeclareLocal(methodInfo.ReturnType); 

     generator.Emit(OpCodes.Ldarg_0); 
     var channelProperty = baseType.GetMethod(ChannelPropertyGetName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty); 

     generator.EmitCall(OpCodes.Call, channelProperty, null); 

     for (short index = 0; index < parameters.Count(); index++) 
      generator.Emit(OpCodes.Ldarg, (index + 1)); 

     generator.Emit(OpCodes.Callvirt, methodInfo); 

     if (isVoid) 
     { 
      generator.Emit(OpCodes.Stloc_0); 
      generator.Emit(OpCodes.Ldloc_0); 
     } 

     generator.Emit(OpCodes.Ret); 

我也有一個服務和相應的服務合同看起來像這樣:

[ServiceContract] 
public interface INamingService 
{ 
    /// <summary> 
    /// Resolve a name 
    /// </summary> 
    [OperationContract(Name = "GetName")] 
    string GetName(string name); 

} 

,但是當我試圖從指定的名稱(NOT NULL)該服務獲取價值,我看到,從客戶端調用出現的參數爲空。因此,就我所知,我在Emit中犯了一個錯誤,參數沒有通過。

任何人都可以告訴我,如何解決這個問題?

+1

我的建議是在C#中編寫你想要的代碼,編譯它,然後比較生成的IL和你爲這個任務發佈的內容。 –

回答

2

這裏有幾個小問題:

  1. isVoid看起來像一個可憐的名字,因爲它表明返回空隙的方法。
  2. 您對本地的使用似乎沒有必要 - 您只需存儲它,然後立即重新加載該值。
  3. 我不明白你爲什麼使用EmitCall屬性獲得者;您應該幾乎肯定會使用Emit(請參閱the documentation)。

但是,我不明白你爲什麼認爲問題出在你的IL一代;對我來說這聽起來更有可能的是,你要麼

  1. 聲明動態方法不正確,或
  2. 莫名其妙誤接線代理。
+0

我已將您的意見納入考慮範圍,謝謝。然而,正如你所說,解決方案奠定了正交的地方 - 我錯誤地定義了綁定。謝謝你的建議 – madcyree