快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

和记娱h188下载app:《WCF技术内幕》翻译36:第2部分第6章通道:创建自定义通道和本章小结



创建自定义通道

上一节已经看过了通道层里的基础类型,现在我们就来创建一个自定义通道。这个通道的目的便是要在节制台窗口里打印一个文本。是以,我们构建的通道对付演示通道的生命周期和法度榜样调用不合的通道成员的时刻都邑异常有用。由于我们的自定义通道会在节制台窗口打印文本,以是有需要通报通道措施的委托调用给客栈里的下一个通道。我们会把这个通道成为委托通道(DelegatorChannel)。在开始之前,有需要指出的是,这里还看不到一个通道运行必须的整个代码,直到第8章“绑定”会整个给出。没法子,创建通道还必要额外的事情。

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

创建基类型

由于所有的通道都要应用通道状态机,并且每个通道必须保留客栈里下一个通道实例的引用,是以把这些属性的声明放在一个基类里对照合理。所有的通道类型都邑承袭自这个基类型,以是把基类型定义为泛型加倍相宜。斟酌到这些需求,我把基类型命名为DelegatorChannelBase,TShape 必须是一个引用类型,而且承袭自IChannel。(记着所有的通道类型都承袭自 IChannel。)DelegatorChannelBase的是ChannelBase的子类型,由于这样它就会应用公共的状态机,并且可以实现Binding 的超时属性。DelegatorChannelBase的初始定义如下:

internal class DelegatorChannelBase : ChannelBase

where TShape : class, IChannel {

// implementation not shown yet

}

添加构造函数

Delegato和记娱h188下载apprChannelBase工具不能放在客栈的底部。换句话说,DelegatorChannelBase工具必须拥有一个通道工具的引用,而且泛型类型表示的是通道外形,我们会把泛型类型作为构造函数的参数。当然构造函数还必要一个通道工厂的引用。当然,一个缘故原由便是为了便于实现绑定的(time-out)超时属性。别的一个缘故原由便是为了在创建通道完毕的时刻可以看护一下通道工厂。你会在第7章里看到更多内容。基类的构造函数定义如下:

internal class DelegatorChannelBase : 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构造函数存储起来。

添加状态机

由于DelegatorChannelBase承袭自抽象类型ChannelBase,并且ChannelBase承袭自抽象类型CommunicationObject但没有实现CommunicationObject里定义的成员,是以 Delegato和记娱h188下载apprChannelBase类型必须实现这些抽象成员。是以 DelegatorChannelBase里的所有状态转换必须传播到客栈里的和记娱h188下载app其它通道,我们的状态转换措施委托会调用 innerChannel通道变量,如下所示:

internal class DelegatorChannelBase : ChannelBase

where TShape : class, IChannel {

private TShape _innerChannel; // reference to the next channel

private String _source; // part of the String to output

// provide the _innerChannel to derived types

protected TShape InnerChannel {

get { return _innerChannel; }

}

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;

}

// IChannel implementation

public override T GetProperty() {

return this._innerChannel.GetProperty();

}

#region CommunicationObject members

protected override void OnAbort() {

PrintHelper.Print(_source, "OnAbort");

this._innerChannel.Abort();

}

protected override IAsyncResult OnBeginClose(TimeSpan timeout,

AsyncCallback callback,

Object state) {

// output that the method was called

PrintHelper.Print( _source, "OnBeginClose");

// delegate the call to the next c和记娱h188下载apphannel

return this._innerChannel.BeginClose(timeout, callback, state);

}

protected override IAsyncResult OnBeginOpen(TimeSpan timeout,

AsyncCallback callback,

Object state) {

// output that the method was called

PrintHelper.Print(_source, "OnBeginOpen");

// delegate the call to the next channel

return this._innerChannel.BeginOpen(timeout, callback, state);

}

protected override void OnClose(TimeSpan timeout) {

// output that the method was called

PrintHelper.Print(_source, "OnClose");

// delegate the call to the next channel

this._innerChannel.Close(timeout);

}

protected override void OnEndClose(IAsyncResult result) {

// output that the method was called

PrintHelper.Print(_source, "OnEndClose");

// delegate the call to the next channel

this._innerChannel.EndClose(result);

}

protected override void OnEndOpen(IAsyncResult result) {

// output that the method was called

PrintHelper.Print(_source, "OnEndOpen");

// delegate the call to the next channel

this._innerChannel.EndOpen(result);

}

protected override void OnOpen(TimeSpan timeout) {

// output that the method was called

PrintHelper.Print(_source, "OnOpen");

// delegate the call to the next channel

this._innerChannel.Open(timeout);

}

#endregion

}

每个状态转换措施(OnAbort、OnBeginClose、OnBeginOpen、OnClose、OnEndClose、OnEndOpen和OnOpen)都邑调用通道上对应的状态转换措施。每个状态转换措施也可以调用PrintHelper类型上的静态措施Print。PrintHelper类型只做在节制台窗口上打印字符的事情。

创建数据报通道

既然我们已经定义了通道的基类型,现在就定义数据报消息互换模式的通道吧。由于数据报发送通道必须承袭IInputChannel接口,接管通道必须承袭IOutputChannel接口,以是我们必要DelegatorChannelBase来承袭这2个接口并实现他们。由于数据报接口被用作双工通信的接口,同时也会做会双工会话通道接口,以是我们把数据报通道定和记娱h188下载app义为泛型。

注释:我们会从接管者开始,然后定义发送者。为了简明扼要,我就不把所有的代码都贴出来,而是着重展示代码里的实现模式。

您可能还会对下面的文章感兴趣: