Lind.DDD.Plugins~插件模式的集成

回到目录

对于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容器的魅力,当然它的基于还是接口,多态和面向对象的基本性质,所以,学好基础才是重中之重!

感谢各位的阅读,非常各位多多关注仓储大叔框架

回到目录

posted @ 2016-10-19 10:39  张占岭  阅读(1642)  评论(1编辑  收藏  举报