C# 插件编程技术学习
定义插件接口
// PluginInterface.cs
// 插件的公用接口
// 编译命令:csc /target:library PluginInterface.cs
using System;
publicinterface IPlugin { // 插件名称string Name { get; }
// 实现插件功能的方法object DoWork(object parameter); }
定义插件宿主接口
// HostInterface.cs
// 插件宿主的公用接口
// 编译命令:csc /target:library HostInterface.cs
using System; using System.Collections.Generic;
publicinterface IHost { // 已经装载的插件的集合 // path为存放插件的目录 List<IPlugin> Plugins { get; }
// 装载所有实现了IPlugin接口的插件 // path为存放插件的目录,返回值为符合要求的插件的数量int LoadPlugins(string path);
// 获取指定的插件 // name为插件的名称 IPlugin GetPlugin(string name); }
编写插件
// Plugin1.cs
// 插件示例
// 编译命令:csc /target:library /r:PluginInterface.dll Plugin1.cs
using System;
publicclass Plugin1 : IPlugin { // 表示插件名的私有字段privatestring name;
// 实现IPlugin的Name属性publicstring Name { get { return name; } }
// 无参数的构造函数public Plugin1() { name ="Plugin1"; }
// 实现IPlugin的DoWork方法publicobject DoWork(object parameter) { Console.WriteLine("================================================"); Console.WriteLine(name +": "+ parameter.ToString()); Console.WriteLine("================================================"); return parameter; } }
// Plugin2.cs
// 插件示例
// 编译命令:csc /target:library /r:PluginInterface.dll Plugin2.cs
using System;
publicclass Plugin2 : IPlugin { // 表示插件名的私有字段privatestring name;
// 实现IPlugin的Name属性publicstring Name { get { return name; } }
// 无参数的构造函数public Plugin2() { name ="Plugin2"; }
// 实现IPlugin的DoWork方法publicobject DoWork(object parameter) { Console.WriteLine("================================================"); Console.WriteLine(name +": "+ parameter.ToString()); Console.WriteLine("================================================"); return parameter; } }
除了插件名不同之外,Plugin1与Plugin2的代码几乎完全相同
编写插件宿主程序
// Host.cs
// 宿主程序
// 编译命令:csc /r:HostInterface.dll /r:PluginInterface.dll Host.cs
using System; using System.IO; using System.Collections.Generic; using System.Reflection;
publicclass Host : IHost { // 私有字段,存放所有已经装载的插件的集合private List<IPlugin> plugins =new List<IPlugin>();
// 实现IHost的Plugins属性public List<IPlugin> Plugins { get { return plugins; } }
// 实现IHost的LoadPlugins方法publicint LoadPlugins(string path) { // 获取指定目录中所有的程序集string[] assemblyFiles = Directory.GetFiles(path, "*.dll"); // 判断每一个程序集是否实现了插件接口IPluginforeach (string file in assemblyFiles) { // 装载程序集 Assembly assembly = Assembly.LoadFrom(file); // 检查程序集中每一个公开的类型foreach (Type t in assembly.GetExportedTypes()) { // 该类型是否类、是否实现了IPlugin接口?if (t.IsClass &&typeof(IPlugin).IsAssignableFrom(t)) { // 创建实现了IPlugin接口的类的对象 IPlugin plugin = Activator.CreateInstance(t) as IPlugin; // 添加到集合中 plugins.Add(plugin); } } }
return plugins.Count; }
// 实现IHost的GetPlugins方法public IPlugin GetPlugin(string name) { foreach (IPlugin ip in plugins) { if (ip.Name == name) return ip; } returnnull; }
// 输入数量的安全方法privatestaticint InputNumber(string prompt) { Console.Write(prompt); string s = Console.ReadLine(); int amount =0; try { amount = Int32.Parse(s); } catch (Exception) // 捕获任何异常 { Console.Write("输入的数值格式不正确,请重新输入!"); // 提示错误 amount = InputNumber(prompt); // 递归调用InputNumber } return amount; }
// 入口点staticvoid Main() { // 创建Host对象 Host h =new Host(); // 装载插件 h.LoadPlugins(".");
// 显示所有已经装载的插件 Console.WriteLine("已经装载如下的插件:"); int i =1; foreach (IPlugin ip in h.Plugins) { Console.WriteLine("{0}. {1}", i++, ip.Name); }
// 选择插件int si = InputNumber("请选择一个插件(按Enter键输入):");
Console.WriteLine("\n");
// 执行插件的功能 IPlugin plugin = h.GetPlugin(h.Plugins[si-1].Name); plugin.DoWork("从宿主程序调用。"); } }
将上述代码编译成应用程序Host.exe。注意,插件宿主程序中同时使用了IHost接口和IPlugin接口,因此,必须同时是程序集HostInterface.dll和PluginInterface.dll。
出处:http://www.cnblogs.com/Tammie/archive/2011/09/13/2174666.html