Welcome

首页 / 软件开发 / WCF / 《WCF技术内幕》36:第2部分_第6章_通道:创建自定义通道和本章小结

《WCF技术内幕》36:第2部分_第6章_通道:创建自定义通道和本章小结2011-06-20 博客园 Frank Xu Lei译创建自定义通道

上一节已经看过了通道层里的基本类型,现在我们就来创建一个自定义通道 。这个通道的目的就是要在控制台窗口里打印一个文本。因此,我们构建的通道 对于演示通道的生命周期和程序调用不同的通道成员的时候都会非常有用。因为 我们的自定义通道会在控制台窗口打印文本,所以有必要传递通道方法的委托调 用给堆栈里的下一个通道。我们会把这个通道成为委托通道(DelegatorChannel )。在开始之前,有必要指出的是,这里还看不到一个通道运行必须的全部代码 ,直到第8章“绑定”会全部给出。没办法,创建通道还需要额外的工作。

创建自定义通道首要考虑的问题就是形状或者是通道要支持的形状。 DelegatorChannel必须支持所有的通道形状(IInputChannel、 IOutputChannel 、IDuplexChannel、IReplyChannel、IRequestChannel以及所有的会话变量)。 因此,我们必须构建多个通道,而且这些通道有固定的层次关系。

创建基类型

因为所有的通道都要使用通道状态机,并且每个通道必须保留堆栈里下一个 通道实例的引用,因此把这些属性的声明放在一个基类里比较合理。所有的通道 类型都会继承自这个基类型,所以把基类型定义为泛型更加合适。考虑到这些需 求,我把基类型命名为DelegatorChannelBase<TShape>,TShape 必须是 一个引用类型,而且继承自IChannel。(记住所有的通道类型都继承自 IChannel。)DelegatorChannelBase<TShape>的是ChannelBase的子类型 ,因为这样它就会使用公共的状态机,并且可以实现Binding 的超时属性。 DelegatorChannelBase<TShape>的初始定义如下:

internal class DelegatorChannelBase<TShape> : ChannelBase

where TShape : class, IChannel {
// implementation not shown yet
}

添加构造函数

DelegatorChannelBase<TShape>对象不能放在堆栈的底部。换句话说 ,DelegatorChannelBase<TShape>对象必须拥有一个通道对象的引用,而 且泛型类型表示的是通道形状,我们会把泛型类型作为构造函数的参数。当然构 造函数还需要一个通道工厂的引用。当然,一个原因就是为了便于实现绑定的( time-out)超时属性。另外一个原因就是为了在创建通道完毕的时候可以通知一 下通道工厂。你会在第7章里看到更多内容。基类的构造函数定义如下:

internal class DelegatorChannelBase<TShape> : ChannelBase
where TShape : class, IChannel {
private TShape _innerChannel; // reference the next channel in the stack
private String _source; // part of the String to print to the console

protected DelegatorChannelBase(ChannelManagerBase channelManagerBase,
TShape innerChannel,
String source) : base(channelManagerBase){
if(innerChannel == null) {
throw new ArgumentNullException("DelegatorChannelBase requires a non-null channel.",
"innerChannel");
}
// set part of the String to print to console
_source = String.Format("{0} CHANNEL STATE CHANGE: DelegatorChannelBase", source);
// set the reference to the next channel
_innerChannel = innerChannel;
}
// other implementation not shown yet
}

注意_innerChannel和_source成员变量。像注释说的,这些成员变量是为了 存储下一个通道的引用和要打印的字符。构造函数的第一个参数是 ChannelManagerBase类型。ChannelManagerBase的引用通过ChannelBase构造函 数存储起来。