开启左侧

C# MEF 通用插件框架

[复制链接]
绝地武士 发表于 2019-8-27 19:56:19 | 显示全部楼层 |阅读模式
废话少说,这个类我封装好了。
首先看下约定:
  1. namespace PluginContract
  2. {
  3.     public interface IPlugin
  4.     {
  5.         string Name { get; set; }
  6.         void SayHello();
  7.     }
  8.     public interface IPluginMark
  9.     {
  10.         string Mark { get; }
  11.     }
  12. }
复制代码
  1. //IPluginMark用来标识MetaData属性
复制代码

自动加载插件类:
  1. public class PlugerBase<T>
  2.     {
  3.         public T GetClass(string className)
  4.         {
  5.             if (Names.Contains(className))
  6.             {
  7.                 var plug = DoPluginList.Where(i => i.Metadata.Mark == className).Select(p => p.Value).FirstOrDefault();
  8.                 return (T)plug;
  9.             }
  10.             else
  11.             {
  12.                 return default(T);
  13.             }
  14.         }
  15.         public string[] Names
  16.         {
  17.             get
  18.             {
  19.                 List<string> name = new List<string>();
  20.                 foreach (var item in DoPluginList)
  21.                 {
  22.                     name.Add(item.Metadata.Mark);
  23.                 }
  24.                 return name.ToArray();
  25.             }
  26.         }
  27.         /// <summary>
  28.         /// 插件列表
  29.         /// </summary>
  30.         [ImportMany]
  31.         private List<Lazy<T, IPluginMark>> DoPluginList = new List<Lazy<T, IPluginMark>>();
  32.         public PlugerBase(string subFolderName="Plug")
  33.         {
  34.             Directory.CreateDirectory(Environment.CurrentDirectory + "\"+ subFolderName);
  35.             var catelog = new AggregateCatalog();
  36.             AssemblyCatalog assemblyCataLog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  37.             catelog.Catalogs.Add(new DirectoryCatalog(subFolderName));
  38.             var container = new CompositionContainer(catelog);
  39.             container.ComposeParts(this);
  40.         }
  41.     }
复制代码

插件端:
第一个:
  1. namespace MEF_Demo//第一个插件实现的插件需要被调用应用的命名空间一致,切记
  2. {
  3.     [ExportMetadata("Mark", "2")]//Mark需要和接口名称同步IPluginMark.后面的2便是GetClass(string className)的className
  4.     [Export(typeof(IPlugin))]
  5.     public class PluginFirst : IPlugin
  6.     {
  7.         public string Name { get; set; } = "张三";

  8.         public void SayHello()
  9.         {
  10.             MessageBox.Show($"你好啊{Name}");
  11.         }
  12.     }
  13. }
复制代码

第二个:
  1. namespace MEF_Demo
  2. {
  3.     [ExportMetadata("Mark","1")]
  4.     [Export(typeof(IPlugin))]
  5.     public class PluginSecod : IPlugin
  6.     {
  7.         public string Name { get; set; } = "李四";
  8.         public void SayHello()
  9.         {
  10.             MessageBox.Show($"你好啊{Name}");
  11.         }
  12.     }
  13. }
复制代码

最后调用时非常简单:
  1. public MainWindow()
  2. {
  3.     InitializeComponent();
  4.     PlugerBase<IPlugin> plug = new PlugerBase<IPlugin>();//编译好的插件需要放置在Plug文件夹内
  5.     var d= plug.GetClass("1");//通过名称直接反射出对应的类
  6.     d.SayHello();

复制代码

原文链接:https://blog.csdn.net/hotmee/article/details/53609052
芜湖小肖 发表于 2019-8-28 10:42:02 | 显示全部楼层
这玩意能干啥用
mxl0323 发表于 2020-7-1 14:32:22 | 显示全部楼层
虽然看不懂,但是觉得很牛逼,哈哈
盈腾电子 发表于 2020-7-7 07:01:09 | 显示全部楼层
支持楼主,开源无价。。
可汗 发表于 2021-5-31 10:47:21 | 显示全部楼层
使用MEF框架的意义并没有减少封装sdk的工作量,从程序扩展性和安全性角度来看,使用此框架很有优势。后续基本上维护dll就可以了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表