C#实现插件式架构
1.定义插件接口,将其编译为DLL
namespace PluginInterface
{
public interface IShow
{
string show();
}
}
2 .编写插件,引用上面的DLL,实现上面定义的接口,也编译为DLL
//插件A
namespace PluginInterface
{
public class PluginA:IShow
{
public string show()
{
return "插件A";
}
}
}
//插件B
namespace PluginB
{
public class PluginB:IShow
{
public string show()
{
return "插件B";
}
}
}
3,在程序中使用插件,需要引用定义插件接口的DLL
namespace testPlugin
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//查找所有的插件的路径
private List<string> FindPlugin()
{
List<string> PluginPaths = new List<string>();
try
{
//获取当前程序的启动路径
string path = Application.StartupPath;
//合并路径,指向插件所在的目录
path = System.IO.Path.Combine(path, "Plugins");
foreach (string fileName in System.IO.Directory.GetFiles(path, "*.dll"))
{
PluginPaths.Add(fileName);
}
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
return PluginPaths;
}
//载入对象
//是在Assembly asm 中查找类型,原来没有这参数
private object LoadObject(Assembly asm,string className, string interfaceName, object[] param)
{
try
{
//取得className的类型
//Type t = Type.GetType(className); 原来是这么写的,无论如何都是返回的null
Type t = asm.GetType(className);
if (t == null
|| !t.IsClass //是否是类
|| !t.IsPublic //是否是公共
|| t.IsAbstract //是否为抽象类
|| t.GetInterface(interfaceName) == null) //是否实现了指定的接口
{
return null;
}
//创建对象
object o = Activator.CreateInstance(t, param);
if (o == null)
{
//创建失败返回null
return null;
}
return o;
}
catch
{
//出现异常返回null
return null;
}
}
//移除无效的插件返回正确的插件路径列表 invalid :无效的
private List<string> DeleteInvalidPlugin(List<string> PluginPaths)
{
string interfaceName = typeof(IShow).FullName;
List<string> RightPluginPaths = new List<string>();
//遍历所有的插件
foreach (string fileName in PluginPaths)
{
try
{
Assembly asm = Assembly.LoadFile(fileName);
// 遍历导出的插件类
foreach (Type t in asm.GetExportedTypes())
{
//查找指定接口
IShow plugin = LoadObject(asm
, t.FullName, interfaceName, null) as IShow;
//如果找到,将插件路径添加到RightPluginPaths,并结束循环
if (plugin != null)
{
RightPluginPaths.Add(fileName);
break;
}
}
}
catch
{
MessageBox.Show(fileName+"不是有效的插件");
}
}
return RightPluginPaths;
}
private void Form1_Load(object sender, EventArgs e)
{
List<string> PluginPaths = FindPlugin();
PluginPaths = DeleteInvalidPlugin(PluginPaths);
foreach (string path in PluginPaths)
{
try
{
//获得 文件名称
string asmFile = path;
string asmName = System.IO.Path.GetFileNameWithoutExtension(asmFile);
if (asmFile != string.Empty)
{
// 利用反射,构造DLL文件的实例
System.Reflection.Assembly asm = System.Reflection.Assembly.LoadFrom(asmFile);
//利用反射,从程序集(DLL)中,提取类,并把此类实例化
//原来这么写的,无法实例化
//
PluginInterface.IShow iShow =
(PluginInterface.IShow)System.Activator.CreateInstance(asm.GetType(asmName
+ "Namespace." + asmName + "Class"));
Type[] t = asm.GetExportedTypes();
foreach (Type type in t)
{
if (type.GetInterface(typeof(IShow).FullName) != null)
{
PluginInterface.IShow iShow = (PluginInterface.IShow)System.Activator.CreateInstance(type);
// 在主程序中使用这个类的实例
label2.Text += iShow.show();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
}