ESFramework介绍之(29)―― 插件公共设施 AddinUtil
(本文适用于 ESFramework V0.2+)
不知你是否还记得,前面我们讲过,ESFramework规定了插件有如下特点:
(1)一个插件是一个独立的物理单元。它可以独立的提供一项完整的服务(功能),而不需要依赖于其它插件。
(2)插件能自我描述 ―― 插件的所有对外的发布信息都由插件自己内部提供,而不依赖于外部文件或注册表。
(3)插件能自我管理 ―― 插件如果需要配置信息,则插件自己能读取和修改配置信息,而不是框架来完成这些事情。
(4)插件自我独立 ―― 一个插件不得引用其它的插件。如果一个插件与另一个插件关系紧密,那么应该将这两个插件合成一个插件,或者重新分解为两个独立的插件。
其实上述特点都为了一个目标,那就是插件的自治及与宿主应用的松耦合。我们希望,插件与宿主应用之间不要有信息共享,或者使这种共享尽可能的少。ESFramework中对插件的支持也很好的遵循了上述特点。但是,有时候应用程序迫不得已需要将某些引用(数据)传递到有需要的插件中,因为插件自己无法直接获取这些引用,而且这些引用可能会被多个组件/插件使用到。插件公共设施AddinUtil(位于ESFramework.Addins命名空间 )提供了一个场所或这说一个容器,宿主应用程序把需要共享给插件的数据放在这个容器中,而需要使用这些数据的插件从AddinUtil获取需要的数据。无疑,AddinUtil最好实现为一个静态类。
{
private static Hashtable htUtil = Hashtable.Synchronized(new Hashtable()) ;
public static void RegisterObject(string name ,object obj)
{
AddinUtil.htUtil.Add(name ,obj) ;
}
public static object GetObject(string name)
{
return AddinUtil.htUtil[name] ;
}
public static void Remove(string name)
{
AddinUtil.htUtil.Remove(name) ;
}
public static void Clear()
{
AddinUtil.htUtil.Clear() ;
}
}
AddinUtil的实现非常简单,就不多讲了。下面举个例子。比如,功能服务器加载的多个功能插件需要解析各自收到的请求消息,消息解析需要IContractHelper组件的协助,IContractHelper的实现通常位于宿主应用(这里是FS)中,在每个插件中都实例化一个IContractHelper组件不仅性能上不划算,而且还可能会导致多个IContractHelper组件实例状态不一致的问题。甚至,更通常的情况,在插件实现中根本不应该看到IContractHelper的实现类,因为IContractHelper的实现类通常位于FS中(或FS引用的dll中),在插件中只能看到IContractHelper接口。
FS在启动的时候,可以将IContractHelper引用注册到AddinUtil:
插件在加载回调IAddin.OnLoading方法中即可从AddinUtil中获取IContractHelper引用:
AddinUtil就像一个中介者,宿主应用不会与任何一个插件紧密耦合,如果宿主应用需要与插件交换数据,通过AddinUtil是一种可行的方式。但是请记住,最好的方案是,宿主应用与插件之间不共享任何数据!只有在不得已的情况下才考虑使用AddinUtil!
上一篇: ESFramework介绍之(28)―― Udp组件
转到 :ESFramework 可复用的通信框架(序)