asp.net mvc 動態編譯生成Controller


做網站后台管理系統的時候,有時我們需要根據用戶的錄入配置動態生成一些頻道,這些頻道需要用到獨立的Controller,這時就需要用到運行時動態編譯了。代碼如下: 

using System.Web.Mvc;
using System.CodeDom.Compiler;
using System.Text;
using Microsoft.CSharp;

namespace DynamicCompiler.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ContentResult Index()
        {
            return Content(@"
                            這個頁面是vs生成的<br> 
                            <a href='/home/creat'>點擊動態編譯生成TestController</a><br>
                            <a href='/Test/'>訪問TestController</a><br>
                            <a href='/Test/WithView'>測試帶View的Action</a>
                        ");
        }

        public ContentResult Creat()
        {
            string cspath = Server.MapPath("~/TestController.cs");
            var compiler = CompilerFromCsPath("TestController", cspath); //編譯

            #region 輸出編譯信息
            StringBuilder sb = new StringBuilder();
            sb.Append("cs文件路徑:" + cspath);

            sb.Append("編譯信息:" + "<br>");
            foreach (string output in compiler.Output)
            {
                sb.Append(output + "<br>");
            }
            sb.Append("錯誤信息:" + "<br>");
            foreach (CompilerError error in compiler.Errors)
            {
                sb.Append(error.ErrorText + "<br>");
            }
            #endregion

            return Content(sb.ToString());
        }

        /// <summary>
        /// 動態編譯並執行代碼
        /// </summary>
        /// <param name="csPath">代碼</param>
        /// <param name="dllName">輸出dll的路徑</param>
        /// <returns>返回輸出內容</returns>
        private CompilerResults CompilerFromCsPath(string dllName, params string[] csPath)
        {
            string binpath = Server.MapPath("~/bin/");
            CSharpCodeProvider complier = new CSharpCodeProvider();
            //設置編譯參數
            CompilerParameters paras = new CompilerParameters();
            //引入第三方dll
            paras.ReferencedAssemblies.Add("System.dll");
            paras.ReferencedAssemblies.Add("System.linq.dll");
            paras.ReferencedAssemblies.Add("System.Web.dll");
            paras.ReferencedAssemblies.Add(binpath + "System.Web.Mvc.dll");
            //是否內存中生成輸出
            paras.GenerateInMemory = false;
            //是否生成可執行文件
            paras.GenerateExecutable = false;
            paras.OutputAssembly = binpath + dllName + ".dll";
            //編譯代碼
            CompilerResults result = complier.CompileAssemblyFromFile(paras, csPath);
            return result;
        }
    }
}

 

流程如下:

 

mvc啟動的時候,只有HomeController,訪問TestController會提示404錯誤

 

然后點擊動態編譯TestController,生成dll到bin目錄。。再點擊訪問TestController的時候,就是可以訪問的狀態了。

 

 

這過程中,mvc應用程序會自動重啟的。。因為我們的配置僅僅是后台使用,我覺得沒必要再去動態加載dll,讓他自動重啟就行了。。不知道這么想對不對。。請大手子賜教。。

 

代碼下載:https://files.cnblogs.com/files/wxb8/%E5%8A%A8%E6%80%81%E7%BC%96%E8%AF%91.zip

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM