在上一篇中我们知道,宿主程序对插件程序定义了一个规约,以此达到和插件程序通讯的目的。那插件有些不平衡,有时候我也需要知道你宿主程序的一些信息来完成我的工作,因此,我必须和你通讯,要有对话的权利。实际上,插件一般都会或多或少的用到宿主程序的上下文,比如vs插件,需要获取vs环境中的编辑的代码对象,才能完成它的工作比如格式化啊统计啊,再比如播放器的歌词插件,至少要获取播放器正在播放的是哪首歌吧。那么我们如何来实现这个通讯呢?我们知道宿主通过一个接口来操作插件,那么同理,插件可以通过一个接口来操作宿主。首先,我们要明确宿主要提供什么属性和方法可供插件们操作,可以提取出一个接口来规约这些行为,那么这个接口就是插件获取宿主context的桥梁。只要插件持有这个接口的引用,实例化时把宿主程序的引用赋上,那么插件便有了对话的权利。稍微改一下上次的代码,如下:
加上一个宿主必须实现的契约:
1public interface IAppContext
2 {
3 //约定宿主程序有一个字符串属性
4 string TextToPrint { get; set; }
5 }
1 public interface IPlugIn
2 {
3 IAppContext App { get; set; }
4 //往控制台上打印东西,这里可以写任何你想要的契约行为
5 void PrintToConsole();
6 }
1 public class SimplePlugIn : IAppContext
2 {
3 string _TextOut = "This is a property of the main program";
4 public string TextToPrint
5 {
6 get { return _TextOut; }
7 set { _TextOut = value; }
8 }
9 ……
10 }
1 foreach (System.Type type in types)
2 {
3 //校验加载的dll是否实现了契约,当然此处也可以用Attribute来实现
4 if (type.GetInterface("IPlugIn") != null)
5 {
6 IPlugIn plugin = (IPlugIn)Activator.CreateInstance(type);
7 plugin.App = this;
8 Plugs.Add(plugin);
9 }
10 }
这样插件中就可以访问宿主程序暴露的属性了
1 //实现了contract里约定的方法,控制台上输出宿主程序的属性TextOut字符串
2 public void PrintToConsole()
3 {
4 Console.WriteLine(m_App.TextToPrint);
5 }
结果如下:
代码下载:https://files.cnblogs.com/Pcant/simplePlun-in2.rar
Austin Liu 刘恒辉
Project Manager and Software Designer E-Mail:lzhdim@163.com Blog:https://lzhdim.cnblogs.com 欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。 |