文章出處

回到目錄

對于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容器的魅力,當然它的基于還是接口,多態和面向對象的基本性質,所以,學好基礎才是重中之重!

感謝各位的閱讀,非常各位多多關注倉儲大叔框架

回到目錄


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()


    留言列表 留言列表

    發表留言