即便现在很多软件都是平台化或者Saas化了,但是用户的定制化需求确是永远存在的;如果单独为某些用户再开发一套软件,相信成本也会高出很多。或者说有的为了方便,直接通过硬编码的方式去实现定制化需求,长此以往,我们就可以见到一座“屎山”了。.
根据以上情况,笔者认为可以采用插件式开发(其实也是很传统的方式了,前面写了几篇反射,这里用到的还是反射,反射在c#中的重要性不言而喻),为不同的用户需求提供不同的插件,如此细分下来,业务和代码层面会简介明了很多。但可能也会带来其他问题,比如插件很多会造成维护困难等;不过相对而言的话,我还是认为此种方式比较优秀;
这篇写了一个简单插件式开发功能的实现,首先就是需要提供一个有约束能力的基类,让所有插件在此标准上实现新的逻辑功能。
这个“基类”可以采用接口来进行约束,也可以采用抽象类(我比较偏向这个方式,因为这样可以直接实现一些公用的、基本的操作,而不需要在每个插件都去实现一次)。
项目结构如下:

实现功能:
- 使用插件式开发实现定制化需求
开发环境:
- 开发工具:Visual Studio 2013
- .NET Framework版本:4.5
实现代码:
//主程序List<Model> List = new List<Model>();readonly string PlugInPath = Application.StartupPath + "\\PlugIns";private void Form1_Load(object sender, EventArgs e){LoadPlugIn();gridPlug.DataSource = new BindingList<Model>(List);}private void LoadPlugIn(){if (!Directory.Exists(PlugInPath)){Directory.CreateDirectory(PlugInPath);}string[] files = Directory.GetFiles(PlugInPath);foreach (string file in files){if (file.ToLower().EndsWith(".dll")){try{Assembly assembly = Assembly.LoadFrom(file);Type[] types = assembly.GetTypes();foreach (Type type in types){if (type.BaseType.FullName == "PlugIn.Base.BaseClass"){object obj = assembly.CreateInstance(type.FullName);string name = type.GetMethod("Name").Invoke(obj, null).ToString();string desc = type.GetMethod("Desc").Invoke(obj, null).ToString();string version = type.GetProperty("Version").GetValue(obj).ToString();List.Add(new Model{Name = name,Desc = desc,Version = version,type=type,Obj = obj});}}}catch (Exception ex){throw ex;}}}}private void btnOpen_Click(object sender, EventArgs e){Process.Start(PlugInPath);}private void btnRun_Click(object sender, EventArgs e){int index=gridPlug.CurrentRow.Index;object obj = List[index].Obj;Type type = List[index].type;object value=type.GetMethod("Run").Invoke(obj, null);MessageBox.Show(Convert.ToString(value));}public class Model{public string Name { get; set; }public string Desc { get; set; }public string Version { get; set; }public Type type { get; set; }public object Obj { get; set; }}
//基类public abstract class BaseClass{public abstract string Name();public abstract string Desc();public abstract string Run();public string Version{get { return "1.0.0"; }}}
//插件1public class One : BaseClass{public override string Name(){return "第一个插件";}public override string Desc(){return "计算2+3";}public override string Run(){return (2 + 3) + "";}}
//插件2public class Two : BaseClass{public override string Name(){return "第二个插件";}public override string Desc(){return "输出HelloWord";}public override string Run(){return "HelloWord";}}
实现效果:
