2016-01-12 22 views
1

我想從一個由Codedom創建的函數返回一個自定義類(例如User)。我的User類在另一個類庫與我的Windows Application相同的解決方案,我用它來動態代碼生成。如何從C#中的CodeDom返回一個自定義類?

CompilerResult返回這些錯誤:

The type or namespace name 'TestApp' could not be found (are you missing a using directive or an assembly reference?) 

The type or namespace name 'User' could not be found (are you missing a using directive or an assembly reference?) 

這裏是我的代碼:

StringBuilder sbCode = new StringBuilder(); 

sbCode.Append(@"using System.Windows.Forms;"); 
sbCode.Append(@"using Nikola.BusinessIntelligence.Objects;"); 
sbCode.Append(@"using System.Collections.Generic;"); 
sbCode.Append(@"using System.Text;"); 
sbCode.Append(@"using Microsoft.CSharp;"); 
sbCode.Append(@"using TestApp.Data;"); // User class is in this Class Lib 

sbCode.Append(" public class Test {"); 
sbCode.Append(tbCode.Text); 
sbCode.Append("}"); 

var cp = new CompilerParameters() 
{ 
    GenerateInMemory = true, 
    GenerateExecutable = false, 
    ReferencedAssemblies = 
    { 
     "System.dll", 
     "System.Core.dll", 
     "System.Windows.dll", 
     "System.Windows.Forms.dll", 
    }, 
}; 

using (CSharpCodeProvider codeProvider = new CSharpCodeProvider()) 
{ 
    CompilerResults res = codeProvider.CompileAssemblyFromSource(cp, sbCode.ToString()); 
    var type = res.CompiledAssembly.GetType("Test"); 
    var obj = Activator.CreateInstance(type); 
    var output = type.GetMethod("Execute").Invoke(obj, new object[] { }); 
} 

這裏是我在tbCode文本框中寫我的示例代碼:

public User Execute() 
     { 
      User usr = new User(); 
      return usr; 
     } 

回答

1

顯然,如果你輸入你的代碼using something;,您必須在CompilerParameters使用引用的程序集的列表中添加something相關引用的程序集:

var cp = new CompilerParameters() 
     { 
      GenerateInMemory = true, 
      GenerateExecutable = false, 
      ReferencedAssemblies = 
      { 
       "System.dll", 
       "System.Core.dll", 
       "System.Windows.dll", 
       "System.Windows.Forms.dll", 
       // I assume the following name of the assembly 
       // however you should update it to the relevant name if needed 
       "TestApp.Data.dll" 
       }, 

     }; 
+0

我的編譯器結果現在沒有任何錯誤,但是這次res.CompiledAssembly.GetType(「Test」);返回null。你有什麼建議嗎? – cagin

+0

您是否調試並檢查類字符串(sbCode)是否形成正確格式? –

+0

@ MohanPrasath,是的,我檢查過它。這是正確的格式 – cagin

1

兩個問題:

  1. 你忘namespace

    sbCode.Append(" namespace SomeNameSpace{public class Test {"); 
    sbCode.Append(tbCode.Text); 
    sbCode.Append("}}"); 
    
  2. 還有就是缺少代碼=你想:

    User usr = new User(); 
    

在編譯器錯誤的問候,你必須添加缺失組件。嘗試通過電流組件添加所有像這樣使用:

var options = new CompilerParameters(); 
// add all loaded assemblies 
options.ReferencedAssemblies.AddRange(
    AppDomain.CurrentDomain.GetAssemblies().Where(item => !item.IsDynamic).Select(item => item.Location).ToArray()); 
options.GenerateExecutable = false; 
options.GenerateInMemory = true; 

// compile like this 
var result = provider.CompileAssemblyFromSource(options, source); 
if (result.Errors.HasErrors) 
{ 
    // deal with errors 
} 
+0

我按照你的說法添加了napespace,現在只能找到類型或命名空間名稱'User'(我缺少一個using指令或程序集引用嗎?)。 – cagin

相關問題