废话少说,这个类我封装好了。
首先看下约定:
- namespace PluginContract
- {
- public interface IPlugin
- {
- string Name { get; set; }
- void SayHello();
- }
- public interface IPluginMark
- {
- string Mark { get; }
- }
- }
复制代码- //IPluginMark用来标识MetaData属性
复制代码
自动加载插件类:
- public class PlugerBase<T>
- {
- public T GetClass(string className)
- {
- if (Names.Contains(className))
- {
- var plug = DoPluginList.Where(i => i.Metadata.Mark == className).Select(p => p.Value).FirstOrDefault();
- return (T)plug;
- }
- else
- {
- return default(T);
- }
- }
- public string[] Names
- {
- get
- {
- List<string> name = new List<string>();
- foreach (var item in DoPluginList)
- {
- name.Add(item.Metadata.Mark);
- }
- return name.ToArray();
- }
- }
- /// <summary>
- /// 插件列表
- /// </summary>
- [ImportMany]
- private List<Lazy<T, IPluginMark>> DoPluginList = new List<Lazy<T, IPluginMark>>();
- public PlugerBase(string subFolderName="Plug")
- {
- Directory.CreateDirectory(Environment.CurrentDirectory + "\"+ subFolderName);
- var catelog = new AggregateCatalog();
- AssemblyCatalog assemblyCataLog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
- catelog.Catalogs.Add(new DirectoryCatalog(subFolderName));
- var container = new CompositionContainer(catelog);
- container.ComposeParts(this);
- }
- }
复制代码
插件端:
第一个:
- namespace MEF_Demo//第一个插件实现的插件需要被调用应用的命名空间一致,切记
- {
- [ExportMetadata("Mark", "2")]//Mark需要和接口名称同步IPluginMark.后面的2便是GetClass(string className)的className
- [Export(typeof(IPlugin))]
- public class PluginFirst : IPlugin
- {
- public string Name { get; set; } = "张三";
- public void SayHello()
- {
- MessageBox.Show($"你好啊{Name}");
- }
- }
- }
复制代码
第二个:
- namespace MEF_Demo
- {
- [ExportMetadata("Mark","1")]
- [Export(typeof(IPlugin))]
- public class PluginSecod : IPlugin
- {
- public string Name { get; set; } = "李四";
- public void SayHello()
- {
- MessageBox.Show($"你好啊{Name}");
- }
- }
- }
复制代码
最后调用时非常简单:
- public MainWindow()
- {
- InitializeComponent();
- PlugerBase<IPlugin> plug = new PlugerBase<IPlugin>();//编译好的插件需要放置在Plug文件夹内
- var d= plug.GetClass("1");//通过名称直接反射出对应的类
- d.SayHello();
- }
复制代码
原文链接:https://blog.csdn.net/hotmee/article/details/53609052 |