您的位置:首页 > 运维架构 > 网站架构

C#实现插件式架构的方法

2015-09-13 18:32 525 查看
  插件式架构,一种全新的、开放性的、高扩展性的架构体系.插件式架构设计近年来非常流行,基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现。扩展功能与框架以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布。基于插件设计并不神秘,相反它比起一团泥的设计更简单,更容易理解。下面已C# .Net简要介绍一下插件式架构的方法.

  定义插件接口,将其编译成dll

namespace PluginInterface
{
public interface IPlugin
{
string Show();
}
}


编写插件,引用上面的DLL,实现上面定义的接口,也编译为DLL

//插件A
namespace PluginA
{
public class PluginA:IPlugin
{
public string Show()
{
return "插件A";
}
}
}

//插件B
namespace PluginB
{
public class PluginB : IPlugin
{
public string Show()
{
return "插件B";
}
}
}


  新建一个控制台程序,需要引用定义插件接口的dll,生成之后,需要在exe所在的目录里建一个Plugins子文件夹,将上面生成的PluginA.dll,和PluginB.dll拷贝进去。

namespace ConsolePluginTest
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
List<string> pluginpath =  p.FindPlugin();

pluginpath = p.DeleteInvalidPlungin(pluginpath);

foreach (string filename in pluginpath)
{
try
{
//获取文件名
string asmfile = filename;
string asmname = Path.GetFileNameWithoutExtension(asmfile);
if (asmname != string.Empty)
{
// 利用反射,构造DLL文件的实例
Assembly asm = Assembly.LoadFile(asmfile);
//利用反射,从程序集(DLL)中,提取类,并把此类实例化
Type[] t = asm.GetExportedTypes();
foreach (Type type in t)
{
if (type.GetInterface("IPlugin") != null)
{
IPlugin show = (IPlugin)Activator.CreateInstance(type);
Console.Write(show.Show());
}
}
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
}
}

//查找所有插件的路径
private List<string> FindPlugin()
{
List<string> pluginpath = new List<string>();
try
{
//获取程序的基目录
string path = AppDomain.CurrentDomain.BaseDirectory;
//合并路径,指向插件所在目录。
path = Path.Combine(path,"Plugins");
foreach (string filename in Directory.GetFiles(path, "*.dll"))
{
pluginpath.Add(filename);
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
return pluginpath;
}
//载入插件,在Assembly中查找类型
private object LoadObject(Assembly asm, string className, string interfacename
, object[] param)
{
try
{
//取得className的类型
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
{
return null;
}
}
//移除无效的的插件,返回正确的插件路径列表,Invalid:无效的
private List<string> DeleteInvalidPlungin(List<string> PlunginPath)
{
string interfacename = typeof(IPlugin).FullName;
List<string> rightPluginPath = new List<string>();
//遍历所有插件。
foreach (string filename in PlunginPath)
{
try
{
Assembly asm = Assembly.LoadFile(filename);
//遍历导出插件的类。
foreach (Type t in asm.GetExportedTypes())
{
//查找指定接口
Object plugin = LoadObject(asm,t.FullName,interfacename,null);
//如果找到,将插件路径添加到rightPluginPath列表里,并结束循环。
if (plugin != null)
{
rightPluginPath.Add(filename);
break;
}
}
}
catch
{
throw new Exception(filename+"不是有效插件");
}
}
return rightPluginPath;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: