回到目錄 對於Lind.DDD這個敏捷框架來說,插件也是其中的一個亮點,所有被認為是插件(Plugins)的模塊都會繼承自IPlugins這個標示介面,它在程式啟動時會找到所有插件,並通過autofac註冊到運行時中,然後在使用時通過PluginManager對象進行獲取,即所有模塊只註冊一次,在使 ...
對於Lind.DDD這個敏捷框架來說,插件也是其中的一個亮點,所有被認為是插件(Plugins)的模塊都會繼承自IPlugins這個標示介面,它在程式啟動時會找到所有插件,並通過autofac註冊到運行時中,然後在使用時通過PluginManager對象進行獲取,即所有模塊只註冊一次,在使用時只是從容器中取出實例的過程,這也保證的程式的性能!
Lind.DDD.Plugins設計圖
一個介面,多個實現,根據具體業務,生產不同的實例,生產的過程前制到程式啟動時,後期的使用直接從容器中獲取,由於是key/value結構,所有獲取的時間複雜度為O(1)
PluginModel模型
將需要動態生產,並且後期可能發生改變的插件持久化到資料庫,文件,Nosql中,程式使用時,直接從存儲介質里讀取即可
/// <summary> /// 插件模型 /// Author:Lind /// 可以被持久化到資料庫里,方便松插撥 /// 根據資料庫的值,生產對應的實例 /// </summary> public class PluginModel : Entity { /// <summary> /// 模塊名稱:對插件進行分類管理 /// </summary> public string ModuleName { get; set; } /// <summary> /// 類型顯示名稱,模塊下麵的類型列表,一個模塊可以有多種類型 /// </summary> public string TypeName { get; set; } /// <summary> /// 類型完整路徑,命令名稱+類名 /// </summary> public string TypeFullName { get; set; } }
PluginManager插件管理者
沒有Init(),Install()這種初始化的方法,而直接集成到了Config屬性上,當沒有初始化時,直接進行註冊註冊插件,當已經被初始化後,直接返回容器即可,這在程式部署時,變得更加自動化!
/// <summary> /// 可插拔組件的管理者 /// Author:Lind /// 依賴於Autofac /// </summary> public class PluginManager { /// <summary> /// 插件容器輔助欄位 /// </summary> private static IContainer _container = null; /// <summary> /// 互斥鎖 /// </summary> private static object lockObj = new object(); /// <summary> /// 類的構造方法 /// </summary> static PluginManager() { lock (lockObj) { if (_container == null) { lock (lockObj) { try { Console.WriteLine("開始註冊(IPlugins)所有插件..."); var builder = new ContainerBuilder(); foreach (var item in AssemblyHelper.GetTypesByInterfaces(typeof(IPlugins))) { builder.RegisterType(item) .Named(item.FullName, item.GetInterfaces().FirstOrDefault()); } _container = builder.Build(); } catch (Exception) { throw new ArgumentException("PluginManager依賴於autofac包包..."); } } } } } /// <summary> /// 從插件容器里返回對象 /// </summary> /// <param name="serviceName"></param> /// <param name="serviceType"></param> /// <returns></returns> public static object Resolve(string serviceName, Type serviceType) { return _container.ResolveNamed(serviceName, serviceType); } /// <summary> /// 從插件容器里返回對象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="serviceName"></param> /// <returns></returns> public static TService Resolve<TService>(string serviceName) { return _container.ResolveNamed<TService>(serviceName); } }
通過這個Lind.DDD.Plugins的設計,讓我們再次領略了IoC容器的魅力,當然它的基於還是介面,多態和麵向對象的基本性質,所以,學好基礎才是重中之重!
感謝各位的閱讀,非常各位多多關註倉儲大叔框架