插件式架構,一種全新的、開放性的、高擴展性的架構體系.插件式架構設計近年來非常流行,基於插件的設計好處很多,把擴展功能從框架中剝離出來,降低了框架的復雜度,讓框架更容易實現。擴展功能與框架以一種很松的方式耦合,兩者在保持接口不變的情況下,可以獨立變化和發布。基於插件設計並不神秘,相反它比起一團泥的設計更簡單,更容易理解。下面已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;
}
}
}
