close

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# 的價值。

arrow
arrow
    全站熱搜

    卑微研究生 發表在 痞客邦 留言(0) 人氣()