F# 號稱動態語言,但跟其它語言整合的話,似乎也只能回到先編譯成 dll 元件的老路。如果想在系統中,隨時可以修改 F# 原始碼並且直接執行,動態編譯後再由 C# 程式呼叫可能是唯一的方法。
為了滿足這個需求,我找了一個開放原始碼的元件:
http://fsharppowerpack.codeplex.com/
這個元件比我想像中的更容易使用,寫出來的程式碼不會太多:
string strSourceCode = (new StreamReader("fsharpFile.fs")).ReadToEnd();
CodeDomProvider provider = new Microsoft.FSharp.Compiler.CodeDom.FSharpCodeProvider();
string[] referenceAssembleList = new string[] { "System.dll", "System.Xml.Linq.dll" };
CompilerParameters cp = new CompilerParameters(referenceAssembleList, @"D:\test.dll");
var compileResult = provider.CompileAssemblyFromSource(cp, new string[] { strSourceCode });
dynamic obj = null;
if (compileResult.Errors.HasErrors)
{
foreach (CompilerError error in compileResult.Errors)
{
Console.WriteLine(error.ErrorText);
}
}
else
{
Assembly assembly = compileResult.CompiledAssembly;
Type t = assembly.GetType("TestFSharp.TestClass");
obj = Activator.CreateInstance(t);
}
Console.WriteLine(obj.Add(1, 2));編譯 F# 的工作是交由 CodeDomProvider 物件來做,值得注意的是,假如 F# 原始碼中有引用到 .net framework 元件,記得設定 CompilerParameters 物件,將參考到的 dll 元件名稱加進去。編譯完後會回傳 CompilerResults,從這個物件就能檢查編譯是否成功,成功則會在指定的路徑產生 dll 元件,失敗的話可以從 Errors 這個屬性檢查失敗的原因。
動態編譯再加上 Reflection 技術,就能再增加系統的彈性,個人認為這樣做才能突顯出 F# 的價值。
文章標籤
全站熱搜
