二三四五还没写,先写六吧(有道友说想看看插件部分)。
这里是一 从零开始编写属于我的CMS:(一)前言
一,首先预定义接口
新建类库,WangCms.PluginInterface
新建两个类,一个实体Models.cs,一个接口IPlugin.cs
Models是插件所用到的实体集合类;IPlugin是为第三方预定义接口,所有插件必须实现该接口。
实体Models代码如下
namespace WangCms.PluginInterface { public class PluginInfo { /// <summary> /// Code /// </summary> public string Code { get; set; } /// <summary> /// 插件名称 /// </summary> public string Name { get; set; } /// <summary> /// 作者 /// </summary> public string Author { get; set; } /// <summary> /// 插件版本 /// </summary> public string Version { get; set; } /// <summary> /// 适用cms版本 /// </summary> public string ApplyVersion { get; set; } /// <summary> /// 描述信息 /// </summary> public string Description { get; set; } //附加信息 public string Area { get; set; } public string AdminController { get; set; } public string AdminAction { get; set; } public string AdminQueryString { get; set; } } public class ResultOptin<T> { public bool State { get; set; } public string Msg { get; set; } public T Result { get; set; } } }
接口IPlufin代码如下
namespace WangCms.PluginInterface { public interface IPlugin { /// <summary> /// 插件注册 /// </summary> /// <returns></returns> ResultOptin<PluginInfo> Register(); /// <summary> /// 插件安装 /// </summary> /// <param name="model"></param> /// <returns></returns> ResultOptin<string> Install(); /// <summary> /// 插件卸载 /// </summary> /// <returns></returns> ResultOptin<string> Uninstall(); } }
二,留言插件
新建一个插件项目(类库),WangCms.Plugin.LiuYan
然后添加相关引用(MVC、WangCms.PluginInterface)等。
首先实现插件接口,新建PluginRegister.cs继承IPlugin,主要为了实现插件的注册、安装以及卸载功能的实现。
PluginRegister代码如下
namespace WangCms.Plugin.LiuYan { public class PluginRegister : IPlugin { #region 实现接口 public ResultOptin<PluginInfo> Register() { ResultOptin<PluginInfo> result = new ResultOptin<PluginInfo>(); try { PluginInfo model = new PluginInfo(); //后台管理入口 model.Area = "LiuYan"; model.AdminController = "LiuYanAdmin"; model.AdminAction = "Index"; model.AdminQueryString = null; //插件基本信息 model.Code = "48a3619327c64a9aa68645007037b451"; model.Name = "在线留言"; model.Author = "千年"; model.Version = "1.0.0"; model.ApplyVersion = "1.0.0"; model.Description = ""; //状态 特别重要 result.State = true; result.Result = model; } catch(Exception ex) { result.State = false; result.Msg = ex.Message; } return result; } public ResultOptin<string> Install() { ResultOptin<string> result = new ResultOptin<string>(); try { //安装插件 //比如执行sql(创建表,插入数据等),创建目录,创建文件等 string sql = @"create table LiuYan( Id varchar(50) primary key, Title varchar(50), Name varchar(50), Contact varchar(50), Content text );"; LiuYanService.Instance.Excute(sql); result.State = true; } catch(Exception ex) { result.State = false; result.Msg = ex.Message; } return result; } public ResultOptin<string> Uninstall() { ResultOptin<string> result = new ResultOptin<string>(); try { //卸载插件 //比如执行sql(删除表,删除数据等),删除目录,删除文件等 string sql = @"drop table LiuYan;"; LiuYanService.Instance.Excute(sql); result.State = true; } catch(Exception ex) { result.State = false; result.Msg = ex.Message; } return result; } #endregion } }
其实,只要实现了接口插件就算完成了,只是该插件还不具备任何实用功能,根据插件名字我想大家知道这个是干嘛的了吧,这就是在线留言的插件,下面就是很简单的留言业务逻辑以及功能的实现了。
插件区域,就是MVC的区域,我们用不同区域来区分和管理插件。
MVC区域,不熟悉的同学可以在园子里搜搜相关文章。
在区域里面可以建Controller和View,还有比较重要的就是区域注册,就是区域的路由吧。
LiuYanAreaRegistration.cs
namespace WangCms.Plugin.LiuYan { public class LiuYanAreaRegistration : AreaRegistration { public override string AreaName { get { return "LiuYan"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "LiuYan_default", "LiuYan/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional }, new string[] { "WangCms.Plugin.LiuYan.Controllers" } ); } } }
然后,就是功能实现了,这部分就略过吧。
在线留言后台管理,新建一个控制器AdminController.cs以及相应的视图。
在线留言前台功能,新建一个控制器PageController.cs以及相应的视图。
三,插件使用
主项目如何使用插件呢?
首先将编译好的插件,上传至主项目下,结构如图。
视图文件和插件时路径一致,WangCms.Plugin.LiuYan.dll上传至主项目bin下。
3.1 获取插件列表
private List<Plugin> GetPluginList() { List<Plugin> list = new List<Plugin>(); string path = Server.MapPath("/bin/"); FileInfo[] files = (new DirectoryInfo(path)).GetFiles("*.dll"); foreach (var item in files) { try { if (!item.Name.StartsWith("WangCms.Plugin.")) continue; Plugin model = new Plugin(); Assembly ass = Assembly.LoadFile(item.FullName); Type tp = ass.GetType(item.Name.Replace(".dll", "") + "." + "PluginRegister"); //获取类名,必须 命名空间+类名 Object obj = Activator.CreateInstance(tp); //建立实例 MethodInfo meth = tp.GetMethod("Register"); //获取方法 object t = meth.Invoke(obj, null); //Invoke调用方法 PluginInterface.ResultOptin<PluginInterface.PluginInfo> result = (PluginInterface.ResultOptin<PluginInterface.PluginInfo>)t; if (result.State)//插件注册成功 { ToPlugin(result.Result, ref model); model.Type = tp; list.Add(model); } } catch { } } return list; }
这里有一个插件类转换的方法。
private void ToPlugin(PluginInterface.PluginInfo t, ref Plugin p) { if (t != null) { p.Code = t.Code; p.Name = t.Name; p.Author = t.Author; p.Version = t.Version; p.ApplyVersion = t.ApplyVersion; p.Description = t.Description; p.AdminController = t.AdminController; p.AdminAction = t.AdminAction; p.AdminQueryString = t.AdminQueryString; } }
3.2 安装插件
public ActionResult plugin_install(string code) { var list = GetPluginList(); var o = list.FirstOrDefault(op => op.Code == code); if (o != null) { //执行安装方法 Object obj = Activator.CreateInstance(o.Type); //建立实例 MethodInfo meth = o.Type.GetMethod("Install"); //获取方法 object t = meth.Invoke(obj, null); //Invoke调用方法 PluginInterface.ResultOptin<string> result = (PluginInterface.ResultOptin<string>)t; if (result.State) { //记录数据 PluginService.Instance.UpdateOrInsert(o); } else { return Content(result.Msg); } } return RedirectToAction("plugin_list"); }
3.3 卸载插件
public ActionResult plugin_uninstall(string code) { var list = GetPluginList(); var o = list.FirstOrDefault(op => op.Code == code); if (o != null) { //执行安装方法 Object obj = Activator.CreateInstance(o.Type); //建立实例 MethodInfo meth = o.Type.GetMethod("Uninstall"); //获取方法 object t = meth.Invoke(obj, null); //Invoke调用方法 PluginInterface.ResultOptin<string> result = (PluginInterface.ResultOptin<string>)t; if (result.State) { //删除数据 PluginService.Instance.DeleteByCode(o.Code); } else { return Content(result.Msg); } } return RedirectToAction("plugin_list"); }
插件源码下载