先说AOP

说到注入,大家就会想起来IoC和AOP,确实如些,这一讲中,我们通过unity来实现对thrift插件的动态注入,事实上,这个功能在以后的项目中经常要用到,比如,你将一些功能分发到指定服务器,而这些服务器的功能是可以动态调整的,每台服务器的插件功能都不相同,这时,如果你有新的插件开发好后,如果不使用AOP的思想,那简直就是灾难!试想,有100个客户端的程序,你将会把新的程序和插件一个个的重新安装到100个客户端电脑上,这是无可厚非的,但如果有了AOP思想,那么,客户端的程序可以实现根据配置文件动态去加载BIN下的DLL的功能,这是吸引人的,呵呵。

再说Thrift容器

Thrift的动态插件需要有一个统一的入口,即所有thrift插件都装到这个入口容器中,事实上,这就是AOP方法拦截的思想,将这些插件的执行控制在某个方法的执行之前或者之后,这是一种巧妙的设计,它解决了不断生产出来的插件的装载问题。

Thrift容器设计,核心代码

Thrift容器有着自己的特色,它需要有一个端口,一个传输协议,和一批动态被加载的Handle,即处理程序(或者叫“插件),我们来看一个代码:

/// <summary>
/// Thrift容器规范
/// </summary>
public interface IThriftHandle
{
/// <summary>
/// 处理程序
/// </summary>
void Handle();
}
/// <summary>
/// 为thrift提供的插件容器
/// </summary>
public class ThriftHandle : IThriftHandle
{
/// <summary>
/// 插件处理器的集合,每当一个插件被激活,
/// 在拦截Hanle()之前,都会前自己的Processor
/// 添加到MultiplexedProcessor中
/// </summary>
public readonly static TMultiplexedProcessor MultiplexedProcessor = new TMultiplexedProcessor();

public void Handle()
{
//远程登陆调用
new Thread(() =>
{
var serverTransport = new TServerSocket(9800);
var server1 = new TThreadedServer(MultiplexedProcessor, serverTransport);
Console.WriteLine("开启扩展服务...");
server1.Serve();
}).Start();
}

OK,我们看到了容器代码之后,对于具体的thrift插件,只要调用MultiplexedProcessor属性的register方法即可完成插件的注册了,而这部分的代码都是在DLL项目里完成的,即一个插件,一个DLL,或者一组类型的插件,一个DLL,这也符合面向对象的原则,即每个插件的职责都是单一的。

看个thrift插件的例子,一个远程命令调用的例子:

/// <summary>
/// 远程命令拦截器
/// </summary>
public class RemoteCommandBehavior : Project.InterceptionBehaviors.InterceptionBase
{
public override IMethodReturn Invoke(
IMethodInvocation input,
GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("远程命令调用开始...");
//注册thrift插件到thrift容器
ThriftHandle.MultiplexedProcessor.RegisterProcessor("RemoteCommandHandler", new RemoteCommandService.Processor(new RemoteCommandHandler()));
return getNext().Invoke(input, getNext);
}
}

RemoteCommandBehavior所对应的Handle处理程序我就省略了,呵呵。

看一下AOP Thrift插件的图示

Thrift架构~动态Thrift插件的注入_客户端

下一讲,我们将分析一下,如何通过thrift实现大文件的断点续传,敬请收看!

作者:仓储大叔,张占岭,
荣誉:微软MVP