2010-09-13 67 views
4

我剛剛發現了.NET ICodeCompiler(請注意,我對它一無所知,只能在程序中運行程序)。我將如何去圍繞這個編寫腳本架構?C#ICodeCompiler - 運行一個類

理想情況下,我希望用戶編寫一些從接口派生的代碼。這個接口將由我在我的程序中定義(它不能由用戶編輯)。用戶會實現它,CompileEngine會運行它。然後我的程序會調用他們已經實現的各種方法。這是可行的嗎?

例如。他們將不得不實現這個:

public interface IFoo 
{ 
    void DoSomething(); 
} 

我會再編譯執行和實例化他們的目的:

// Inside my binary 
IFoo pFooImpl = CUserFoo; 
pFooImpl.DoSomething(); 

回答

2

你想達到什麼是可能的,但請注意! 每次編譯代碼時,它都會作爲程序集編譯並加載到內存中。如果更改「腳本」代碼並重新編譯,它將作爲另一個程序集再次加載。這可能會導致「內存泄漏」(儘管它不是真正的泄漏),並且無法卸載那些未使用的程序集。

唯一的解決方案是創建另一個AppDomain並在該AppDomain中加載該程序集,然後在代碼更改並重新執行時卸載該程序集。但這樣做比較困難。

UPDATE

對於編譯看看這裏: http://support.microsoft.com/kb/304655

然後,你將不得不使用加載Assembly.LoadFrom 組裝。

// assuming the assembly has only ONE class 
    // implementing the interface and method is void 
    private static void CallDoSomething(string assemblyPath, Type interfaceType, 
     string methodName, object[] parameters) 
    { 
     Assembly assembly = Assembly.LoadFrom(assemblyPath); 
     Type t = assembly.GetTypes().Where(x=>x.GetInterfaces().Count(y=>y==interfaceType)>0).FirstOrDefault(); 
     if (t == null) 
     { 
      throw new ApplicationException("No type implements this interface"); 
     } 
     MethodInfo mi = t.GetMethods().Where(x => x.Name == methodName).FirstOrDefault(); 
     if (mi == null) 
     { 
      throw new ApplicationException("No such method"); 
     } 
     mi.Invoke(Activator.CreateInstance(t), parameters); 
    } 
+0

如果需要,我可以提供代碼。 – Aliostad 2010-09-13 18:06:47

+0

請做。我也想知道這是否會將我在代碼中設計的任何接口傳播到用戶設計代碼中。 – MarkP 2010-09-13 18:19:33

+0

看看這裏:http://support.microsoft.com/kb/304655 – Aliostad 2010-09-13 18:23:27

1

如果我理解正確,你想做的事,我想的CodeDOM和this article可以幫助你。這是你在找什麼?