对于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容器的魅力,当然它的基于还是接口,多态和面向对象的基本性质,所以,学好基础才是重中之重!
感谢各位的阅读,非常各位多多关注仓储大叔框架