将静态分配器架构与静态Client-Dispatcher-Server模式做比较
静态分配器非常类似于插件架构,因为程序集在运行时加载。让我们将它与静态Client-Dispatcher-Server模式做比较。插件(plug-in)是动态加载的实现某个特殊接口的程序集。在分配器的上下文环境中,意味着服务器就是插件。分配器通过某种将接口实例跟类型相关联的解析技术来管理插件。例如,如果ExternalServer类型在程序集ExternalServer.dll中实现,那么可以像下面
这样编写分配器:
class Dispatcher {
public type CreateInstance<type>( string assemblyPath, string @class) {
Assembly assembly; assembly = Assembly.Load(
AssemblyName.GetAssemblyName( assemblyPath )); return (type)assembly.CreateInstance( @class);
class Client {
public void DoSomething() {
IExternal obj = CreateInstance<IExternal>( "ExternalServers.dll", "ExternalServer"); Il Do something with obj
Dispatcher类型只有一个方法CreateInstance,它能够动态地加载程序集ExternalServers.dll并实例化ExternalServers类型。Assembly.Load方法加载程序集,而assembly.CreateInstance方法实例化加载后的程序集中的类型。CreateInstance方法使用泛型来把
Object类型转换成需要的类型。
这种动态加载并实例化类型的解决方案工作得非常好,唯一一个缺点就是如果这个程序集被修改了,那么任何已经加载的程序集都不能被卸载。如果这个应用程序是个程序集在执行时不会修改的客户代码应用,那么Dispatcher类型就足够好了。如果应用程序是在服
务器端运行,那么重新加载插件就是个问题。在CreateInstance<IExternal>方法调用中的字符串标识符是硬编码的。
Client-Dispatcher-Server模式的一个主要附加特征是分配器必须含有将标识符解析成程序集中的类型的功能。在这个简单的例子中,Dispatcher类型假设客户代码是知道引用标识符的。此Dispatcher增加的值是知道程序集和类型所处的路径名称的。
不清楚的请看文章:调用DoSomething方法,处理错误与状态
纯粹从模式的角度来看,可能存在这样的争议:这个简单的例子不是分配器的实现,因为服务器并没有联系Dispatcher并注册自己。的确是这样,但我想更加灵活地表现出分配器的真正行为,让服务器与分配器联系并注册自己,在我看来,只是实现分配器的途径之
一。就如同将在下面的章节中看到的一样,Client-Dispatcher-Server模式能够实现并扩展其他模式。
作为通用规则,分配器负责把标识符解析成类型和程序集。类型和程序集的解析可以以下面的方式发生:
配置文件:分配器加载并处理配置文件。当需要实例化特殊的类型时,分配器使用配置信息来交叉引用请求的类型。这种方法的好处是可以在运行时对应用程序进行配置,并且可以使用版本信息在特定的上下文环境中加载特定的版本。这种方法的缺点在于管理员需
要从开发者那里获取关于可用插件实现的文档,而且错误的配置文件会在调试生产问题时导致破坏。
程序集目录:使用配置文件指定一个或多个包含大量程序集的目录。分配器读取目录并遍历里面可用的程序集。每个程序集都有类型信息被抽取出来存在一个列表中。每当类型有实例化需求的时候,这个列表就会交叉引用到类型和程序集的标识符。这种方法的优势
是只需要最少的配置信息,因为发生的是动态解析,而且如果保留了合适版本的程序,应用程序就可以自我修复。这种方法的缺点是,加载和实例化逻辑是硬编码在分配器内部的,也就是说逻辑改变需要重启应用程序。另一个缺点就是应用程序开发者在开发的时候必须
知道所使用插件实现的标识符。
工厂委托:对于这种解决方案,程序集作为配置文件中一个目录或个体被引用。动态加载程序集但不抽取类型信息。分配器寻找一个Factory模式来把自己钩在分配器上。当发出实例化请求时分配器就委托给Factory模式。这种方法的好处是实例化委托给了插件实现
,允许实现来决定用哪种逻辑实例化类型。而且微内核或者内部服务实现委托,允许程序集处理自己的版本和标识符交叉引用。这种方法的缺点在于每个程序集都必须实现一个标准类型来作为类型实例化的入口点,每个程序集都负责指定实例化哪个类型,这会给开发者
带来额外的编码工作。
服务器注册:在这种解决方案中,分配器什么也不知道,通过分配器注册类型信息是服务器的责任。这种方法的问题是一些程序不得不启动服务器并指示分配器在哪,这增加了服务器的负担。这种方法的优势是类型能够在服务需要它的时候进行动态转换。其他解析
技术都不够灵活,即使它们很简单。
分析完四种解析技术,我们发现对于执行解析没有一种最好的方法,每种方法都有它的优缺点。你不得不根据实际情况决定哪种解决方案是最合适的。 之前用 程序集目录 做过插件。
页:
[1]