二三四五還沒寫,先寫六吧(有道友說想看看插件部分)。 這裡是一 從零開始編寫屬於我的CMS:(一)前言 一,首先預定義介面<!--?xml:namespace prefix = "o" ns = "urn:schemas-microsoft-com:office:office" /--> 新建類庫, ...
二三四五還沒寫,先寫六吧(有道友說想看看插件部分)。
這裡是一 從零開始編寫屬於我的CMS:(一)前言
一,首先預定義介面
新建類庫,WangCms.PluginInterface
新建兩個類,一個實體Models.cs,一個介面IPlugin.cs
Models是插件所用到的實體集合類;IPlugin是為第三方預定義介面,所有插件必須實現該介面。
實體Models代碼如下
1 namespace WangCms.PluginInterface 2 { 3 public class PluginInfo 4 { 5 /// <summary> 6 /// Code 7 /// </summary> 8 public string Code { get; set; } 9 /// <summary> 10 /// 插件名稱 11 /// </summary> 12 public string Name { get; set; } 13 /// <summary> 14 /// 作者 15 /// </summary> 16 public string Author { get; set; } 17 /// <summary> 18 /// 插件版本 19 /// </summary> 20 public string Version { get; set; } 21 /// <summary> 22 /// 適用cms版本 23 /// </summary> 24 public string ApplyVersion { get; set; } 25 /// <summary> 26 /// 描述信息 27 /// </summary> 28 public string Description { get; set; } 29 30 31 //附加信息 32 public string Area { get; set; } 33 public string AdminController { get; set; } 34 public string AdminAction { get; set; } 35 public string AdminQueryString { get; set; } 36 } 37 public class ResultOptin<T> 38 { 39 public bool State { get; set; } 40 public string Msg { get; set; } 41 42 public T Result { get; set; } 43 } 44 }
介面IPlufin代碼如下
1 namespace WangCms.PluginInterface 2 { 3 public interface IPlugin 4 { 5 /// <summary> 6 /// 插件註冊 7 /// </summary> 8 /// <returns></returns> 9 ResultOptin<PluginInfo> Register(); 10 /// <summary> 11 /// 插件安裝 12 /// </summary> 13 /// <param name="model"></param> 14 /// <returns></returns> 15 ResultOptin<string> Install(); 16 /// <summary> 17 /// 插件卸載 18 /// </summary> 19 /// <returns></returns> 20 ResultOptin<string> Uninstall(); 21 } 22 }
二,留言插件
新建一個插件項目(類庫),WangCms.Plugin.LiuYan
然後添加相關引用(MVC、WangCms.PluginInterface)等。
首先實現插件介面,新建PluginRegister.cs繼承IPlugin,主要為了實現插件的註冊、安裝以及卸載功能的實現。
PluginRegister代碼如下
1 namespace WangCms.Plugin.LiuYan 2 { 3 public class PluginRegister : IPlugin 4 { 5 #region 實現介面 6 public ResultOptin<PluginInfo> Register() 7 { 8 ResultOptin<PluginInfo> result = new ResultOptin<PluginInfo>(); 9 try 10 { 11 PluginInfo model = new PluginInfo(); 12 //後臺管理入口 13 model.Area = "LiuYan"; 14 model.AdminController = "LiuYanAdmin"; 15 model.AdminAction = "Index"; 16 model.AdminQueryString = null; 17 18 //插件基本信息 19 model.Code = "48a3619327c64a9aa68645007037b451"; 20 model.Name = "線上留言"; 21 model.Author = "千年"; 22 model.Version = "1.0.0"; 23 model.ApplyVersion = "1.0.0"; 24 model.Description = ""; 25 26 //狀態 特別重要 27 result.State = true; 28 result.Result = model; 29 } 30 catch(Exception ex) 31 { 32 result.State = false; 33 result.Msg = ex.Message; 34 } 35 return result; 36 } 37 38 public ResultOptin<string> Install() 39 { 40 ResultOptin<string> result = new ResultOptin<string>(); 41 try 42 { 43 //安裝插件 44 //比如執行sql(創建表,插入數據等),創建目錄,創建文件等 45 string sql = 46 @"create table LiuYan( 47 Id varchar(50) primary key, 48 Title varchar(50), 49 Name varchar(50), 50 Contact varchar(50), 51 Content text 52 );"; 53 LiuYanService.Instance.Excute(sql); 54 result.State = true; 55 } 56 catch(Exception ex) 57 { 58 result.State = false; 59 result.Msg = ex.Message; 60 } 61 return result; 62 } 63 64 public ResultOptin<string> Uninstall() 65 { 66 ResultOptin<string> result = new ResultOptin<string>(); 67 try 68 { 69 //卸載插件 70 //比如執行sql(刪除表,刪除數據等),刪除目錄,刪除文件等 71 string sql = @"drop table LiuYan;"; 72 LiuYanService.Instance.Excute(sql); 73 result.State = true; 74 } 75 catch(Exception ex) 76 { 77 result.State = false; 78 result.Msg = ex.Message; 79 } 80 return result; 81 } 82 #endregion 83 } 84 }
其實,只要實現了介面插件就算完成了,只是該插件還不具備任何實用功能,根據插件名字我想大家知道這個是幹嘛的了吧,這就是線上留言的插件,下麵就是很簡單的留言業務邏輯以及功能的實現了。
插件區域,就是MVC的區域,我們用不同區域來區分和管理插件。
MVC區域,不熟悉的同學可以在園子里搜搜相關文章。
在區域裡面可以建Controller和View,還有比較重要的就是區域註冊,就是區域的路由吧。
LiuYanAreaRegistration.cs
1 namespace WangCms.Plugin.LiuYan 2 { 3 public class LiuYanAreaRegistration : AreaRegistration 4 { 5 public override string AreaName 6 { 7 get 8 { 9 return "LiuYan"; 10 } 11 } 12 13 public override void RegisterArea(AreaRegistrationContext context) 14 { 15 context.MapRoute( 16 "LiuYan_default", 17 "LiuYan/{controller}/{action}/{id}", 18 new { action = "Index", id = UrlParameter.Optional }, 19 new string[] { "WangCms.Plugin.LiuYan.Controllers" } 20 ); 21 } 22 } 23 }
然後,就是功能實現了,這部分就略過吧。
線上留言後臺管理,新建一個控制器AdminController.cs以及相應的視圖。
線上留言前臺功能,新建一個控制器PageController.cs以及相應的視圖。
三,插件使用
主項目如何使用插件呢?
首先將編譯好的插件,上傳至主項目下,結構如圖。
視圖文件和插件時路徑一致,WangCms.Plugin.LiuYan.dll上傳至主項目bin下。
3.1 獲取插件列表
1 private List<Plugin> GetPluginList() 2 { 3 List<Plugin> list = new List<Plugin>(); 4 string path = Server.MapPath("/bin/"); 5 FileInfo[] files = (new DirectoryInfo(path)).GetFiles("*.dll"); 6 foreach (var item in files) 7 { 8 try 9 { 10 if (!item.Name.StartsWith("WangCms.Plugin.")) continue; 11 Plugin model = new Plugin(); 12 Assembly ass = Assembly.LoadFile(item.FullName); 13 Type tp = ass.GetType(item.Name.Replace(".dll", "") + "." + "PluginRegister"); //獲取類名,必須 命名空間+類名 14 Object obj = Activator.CreateInstance(tp); //建立實例 15 MethodInfo meth = tp.GetMethod("Register"); //獲取方法 16 object t = meth.Invoke(obj, null); //Invoke調用方法 17 18 PluginInterface.ResultOptin<PluginInterface.PluginInfo> result = (PluginInterface.ResultOptin<PluginInterface.PluginInfo>)t; 19 if (result.State)//插件註冊成功 20 { 21 ToPlugin(result.Result, ref model); 22 model.Type = tp; 23 list.Add(model); 24 } 25 } 26 catch { } 27 } 28 29 30 return list; 31 }
這裡有一個插件類轉換的方法。
1 private void ToPlugin(PluginInterface.PluginInfo t, ref Plugin p) 2 { 3 if (t != null) 4 { 5 p.Code = t.Code; 6 p.Name = t.Name; 7 p.Author = t.Author; 8 p.Version = t.Version; 9 p.ApplyVersion = t.ApplyVersion; 10 p.Description = t.Description; 11 p.AdminController = t.AdminController; 12 p.AdminAction = t.AdminAction; 13 p.AdminQueryString = t.AdminQueryString; 14 } 15 }View Code
3.2 安裝插件
1 public ActionResult plugin_install(string code) 2 { 3 var list = GetPluginList(); 4 5 var o = list.FirstOrDefault(op => op.Code == code); 6 if (o != null) 7 { 8 //執行安裝方法 9 Object obj = Activator.CreateInstance(o.Type); //建立實例 10 MethodInfo meth = o.Type.GetMethod("Install"); //獲取方法 11 object t = meth.Invoke(obj, null); //Invoke調用方法 12 13 PluginInterface.ResultOptin<string> result = (PluginInterface.ResultOptin<string>)t; 14 if (result.State) 15 { 16 //記錄數據 17 PluginService.Instance.UpdateOrInsert(o); 18 } 19 else 20 { 21 return Content(result.Msg); 22 } 23 } 24 return RedirectToAction("plugin_list"); 25 }
3.3 卸載插件
1 public ActionResult plugin_uninstall(string code) 2 { 3 var list = GetPluginList(); 4 5 var o = list.FirstOrDefault(op => op.Code == code); 6 if (o != null) 7 { 8 //執行安裝方法 9 Object obj = Activator.CreateInstance(o.Type); //建立實例 10 MethodInfo meth = o.Type.GetMethod("Uninstall"); //獲取方法 11 object t = meth.Invoke(obj, null); //Invoke調用方法 12 13 PluginInterface.ResultOptin<string> result = (PluginInterface.ResultOptin<string>)t; 14 if (result.State) 15 { 16 //刪除數據 17 PluginService.Instance.DeleteByCode(o.Code); 18 } 19 else 20 { 21 return Content(result.Msg); 22 } 23 } 24 return RedirectToAction("plugin_list"); 25 }
插件源碼下載