從零開始編寫屬於我的CMS:(六)插件

来源:http://www.cnblogs.com/deeround/archive/2016/08/19/5789026.html
-Advertisement-
Play Games

二三四五還沒寫,先寫六吧(有道友說想看看插件部分)。 這裡是一 從零開始編寫屬於我的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

 

 

然後添加相關引用(MVCWangCms.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區域,不熟悉的同學可以在園子里搜搜相關文章。

在區域裡面可以建ControllerView,還有比較重要的就是區域註冊,就是區域的路由吧。

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         }

 

 插件源碼下載

插件源碼下載

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 資源表是一個樹形結構,可以設置成2的31次方的層數,Windows 使用了3級: 類型->名稱->語言 其中涉及到四個結構: Data Description Resource Directory Tables (and Resource Directory Entries) A series of... ...
  • 介紹 LINQ(目錄) 語言集成查詢 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5 版中引入的一項創新功能。 傳統上,針對數據的查詢都是以簡單的字元串表示,而沒有編譯時類型檢查或 IntelliSense 支持。 此外,您還必須針對以下各種數據源學 ...
  • 開始使用 LINQ (一)- 介紹 LINQ 查詢 查詢是一種從數據源檢索數據的表達式。 隨著時間的推移,人們已經為各種數據源開發了不同的語言;例如,用於關係資料庫的 SQL 和用於 XML 的 XQuery。 因此,開發人員不得不針對他們必須支持的每種數據源或數據格式而學習新的查詢語言。 LINQ ...
  • 開始使用 LINQ (二)- 基本 LINQ 查詢操作 一、獲取數據源:from 在 LINQ 查詢中,第一步是指定數據源。像在大多數編程語言中一樣,在 C# 中,必須先聲明變數,才能使用它。在 LINQ 查詢中,最先使用 from 子句的目的是引入數據源 (customers) 和範圍變數 (cu ...
  • 開始使用 LINQ(三)- 使用 LINQ 進行數據轉換 語言集成查詢 (LINQ) 不僅可用於檢索數據, 而且還是一個功能強大的數據轉換工具。 通過使用 LINQ 查詢,您可以將源序列用作輸入,並採用多種方式修改它以創建新的輸出序列。您可以通過排序和分組來修改該序列,而不必修改元素本身。但是,LI ...
  • 補充下上篇文章集合的命令。 上篇地址 博客園蝸牛 http://www.cnblogs.com/tdws/p/5785939.html SCARD Key獲得執行集合中元素的數量。 SDIFFSTORE 目標鍵 keys ... 將集合做DIFF差集操作,並存儲在目標鍵中。 另外同樣有SINTERS ...
  • 通常情況下我們在使用IBatisNet的時候,配置文件和映射文件都是暴露在外的,如果能進入到伺服器,那麼你的程式的操作資料庫的SQL語句,資料庫連接字元串等信息都將很輕鬆的被看到,這樣是很危險的。然而IBatisnet自身也沒有提供配置文件直接加密的方法,但我們可以用變通的方式來儘可能的保護這些文件 ...
  • 本隨筆續接:.NET 實現並行的幾種方式(一) 四、Task 3)Task.NET 4.5 中的簡易方式 在上篇隨筆中,兩個Demo使用的是 .NET 4.0 中的方式,代碼寫起來略顯麻煩,這不 .NET 4.5提供了更加簡潔的方式,讓我們來看一下吧。 /// <summary> /// Task. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...