您的位置:首页 > 其它

《WCF技术内幕》翻译39:第2部分_第7章_通道管理器:通道工厂和本章小结

2010-01-20 22:26 519 查看
本节目录:
发送者:通道工厂
IChannelFactory接口
IChannelFactory<TChannel>接口
The ChannelFactoryBase Type ChannelFactoryBase类型
ChannelFactoryBase<TChannel>类型
创建自定义通道工厂
本章小结

[align=left]发送者:通道工厂[/align]
[align=left]发送者使用通道工厂来创建通道。它们和通道侦听器的许多特性相似,但是不同的是它们驻留在发送者内部,而且不需要从连接上侦听消息。它们会通过CreateChannel方法创建符合要求的连接通道而不是消极等待消息到来。和通道侦听器一样,通道工厂也是根据它们创建的通道功能来分类的。[/align]
[align=left]实际上,这意味着每个传输通道都会有一个与之关联的通道工厂,比如支持WS-*协议的通道。和通道侦听器一样,用户代码无法直接实例化通道工厂,需要借助于Binding(你会在第8章里看到详细的介绍)。通道工厂类型都继承自ChannelManagerBase。而类型层次的其它部分则不相同。本节里,我们会先研究一下通道工厂里不同的类型,然后会创建一个自定义通道工厂来继续学习我们的DelegatorChannel例子。[/align]
[align=left]IChannelFactory接口[/align]
[align=left]所有的通道工厂都继承了IChannelFactory接口。这个接口实现了ICommunicationObject接口,因此可以强制它的继承者实现通道状态机。当然还有就是暴露与通道和通道侦听器里类似的一个查询机制。代码如下所示:[/align]
[align=left]public interface IChannelFactory : ICommunicationObject {[/align]
[align=left] T GetProperty<T>() where T: class;[/align]
[align=left]}[/align]
[align=left]IChannelFactory<TChannel>接口[/align]
[align=left]所有的通道工厂也都实现了IChannelFactory<TChannel>接口。这个接口继承自IChannelFactory,所以它比IChannelFactory的用处更广。IChannelFactory<TChannel>定义了2个成员,如下所示:[/align]
[align=left]public interface IChannelFactory<TChannel> : IChannelFactory {[/align]
[align=left] TChannel CreateChannel(EndpointAddress to);[/align]
[align=left] TChannel CreateChannel(EndpointAddress to, Uri via);[/align]
[align=left]}[/align]
[align=left]CreateChannel方法包含2个参数。它们是EndpointAddress和Uri类型。在运行时,这些参数会序列化到消息里,via参数就是通道要尝试连接的地址,to是发送消息的地址。中间可能经过消息的中转(第2章里曾经讲到)。
ChannelFactoryBase
类型[/align]
[align=left]通道工厂简介继承了抽象类型ChannelFactoryBase。概念上,它的作用与通道侦听器里使用的ChannelListenerBase类型一样。换句话说,ChannelListenerBase类型也提供了一种自定义打开、关闭、发送和接受消息超时属性的方式。它的对象模型如下所示:[/align]
[align=left]public abstract class ChannelFactoryBase : ChannelManagerBase,[/align]
[align=left] IChannelFactory {[/align]
[align=left] protected ChannelFactoryBase();[/align]
[align=left] protected ChannelFactoryBase(IDefaultCommunicationTimeouts timeouts);[/align]
[align=left] // IChannelFactory implementation[/align]
[align=left] public virtual T GetProperty<T>() where T: class;[/align]
[align=left] // CommunicationObject implementation[/align]
[align=left] protected override void OnAbort();[/align]
[align=left] protected override IAsyncResult OnBeginClose(TimeSpan timeout,[/align]
[align=left] AsyncCallback callback,[/align]
[align=left] Object state);[/align]
[align=left] protected override void OnClose(TimeSpan timeout);[/align]
[align=left] protected override void OnEndClose(IAsyncResult result);[/align]
[align=left] protected override TimeSpan DefaultCloseTimeout { get; }[/align]
[align=left] protected override TimeSpan DefaultOpenTimeout { get; }[/align]
[align=left] // ChannelManagerBase implementation[/align]
[align=left] protected override TimeSpan DefaultReceiveTimeout { get; }[/align]
[align=left] protected override TimeSpan DefaultSendTimeout { get; }[/align]
[align=left]}[/align]
[align=left]ChannelFactoryBase<TChannel>类型[/align]
[align=left]ChannelFactoryBase<TChannel>类型继承了ChannelFactoryBase类型,而且实现了IChannelFactory<TChannel>接口。它也是通道工厂类型的基类。更进一步说,这个类型维护和控制通道的创建状态。(想一下本章前面“通道管理器的概念”一节。)ChannelFactoryBase<TChannel>的对象模型如下:[/align]
[align=left]public abstract class ChannelFactoryBase<TChannel> : ChannelFactoryBase,[/align]
[align=left] IChannelFactory<TChannel> {[/align]
[align=left] // calls the other constructor, passing null as argument[/align]
[align=left] protected ChannelFactoryBase();[/align]
[align=left] // creates an object that manages the channels[/align]
[align=left] protected ChannelFactoryBase(IDefaultCommunicationTimeouts timeouts);[/align]
[align=left] // IChannelFactory<TChannel> implementation[/align]
[align=left] public TChannel CreateChannel(EndpointAddress address);[/align]
[align=left] public TChannel CreateChannel(EndpointAddress address, Uri via);[/align]
[align=left] // Extensibility point for IChannelFactory<TChannel> implementation[/align]
[align=left] protected abstract TChannel OnCreateChannel(EndpointAddress address, Uri via);[/align]
[align=left] // CommunicationObject implementation: changes state[/align]
[align=left] // of the channels it has created[/align]
[align=left] protected override void OnAbort();[/align]
[align=left] protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback,[/align]
[align=left]object state);[/align]
[align=left] protected override void OnClose(TimeSpan timeout);[/align]
[align=left] protected override void OnEndClose(IAsyncResult result);[/align]
[align=left] // helper method that checks the State to see if the[/align]
[align=left] // channel factory can create channels (CommunicationState.Opened)[/align]
[align=left] protected void ValidateCreateChannel();[/align]
[align=left]}[/align]
[align=left]ChannelFactoryBase<TChannel>的构造函数实例化了一个对象,这个对象可以保存工厂里创建的通道对象的引用。当ChannelFactoryBase<TChannel>对象关闭或者终止的时候,这个对象可以确保引用的通道状态机与ChannelFactoryBase<TChannel>对象状态一致。这些代码确保状态改变发生在ChannelFactoryBase<TChannel> 里CommunicationObject的实现里。[/align]
[align=left]ChannelFactoryBase<TChannel>另外一个有趣的地方就是ValidateCreateChannel方法。这个方法仅仅是为了确保对象的状态是CommunicationState.Opened。如果状态不是,这个方法就会抛出一个InvalidOperationException异常。两个CreateChannel方法都会调用这个方法来确保通道工厂处于正确的状态。[/align]
[align=left]创建自定义通道工厂[/align]
[align=left]既然已经学习了通道工厂里重要的相关类型,现在我们来创建一个自定义通道工厂,继续完成我们的DelegatorChannel例子。和前面的DelegatorChannelListener<TShape>例子类似,我们的通道工厂必须可以创建任何形状的通道。因此,我们的通道工厂必须使用泛型,如下所示:[/align]
[align=left]internal sealed class DelegatorChannelFactory<TShape> :[/align]
[align=left] ChannelFactoryBase<TShape> {[/align]
[align=left] // reference the next channel factory in the stack[/align]
[align=left] IChannelFactory<TShape> _innerFactory;[/align]
[align=left] // the String to print to the console[/align]
[align=left] String _consolePrefix = "FACTORY: DelegatorChannelFactory";[/align]
[align=left] // ctor that builds the next channel factory in the stack,[/align]
[align=left] // then assigns the _innerFactory member variable[/align]
[align=left] internal DelegatorChannelFactory(BindingContext context) {[/align]
[align=left] PrintHelper.Print(_consolePrefix, "ctor");[/align]
[align=left] this._innerFactory = context.BuildInnerChannelFactory<TShape>();[/align]
[align=left] }[/align]
[align=left] // instantiates and returns a DelegatorChannel that[/align]
[align=left] // references another channel[/align]
[align=left] private TShape WrapChannel(TShape innerChannel) {[/align]
[align=left] if(innerChannel == null) {[/align]
[align=left] throw new ArgumentNullException("innerChannel cannot be null",[/align]
[align=left] "innerChannel");[/align]
[align=left] }[/align]
[align=left] if(typeof(TShape) == typeof(IOutputChannel)) {[/align]
[align=left] return (TShape)(Object) new DelegatorOutputChannel<IOutputChannel>[/align]
[align=left] (this, (IOutputChannel)innerChannel, "SEND");[/align]
[align=left] }[/align]
[align=left] if(typeof(TShape) == typeof(IRequestChannel)) {[/align]
[align=left] return (TShape)(Object) new DelegatorRequestChannel[/align]
[align=left] (this, (IRequestChannel)innerChannel, "SEND");[/align]
[align=left] }[/align]
[align=left] if(typeof(TShape) == typeof(IDuplexChannel)) {[/align]
[align=left] return (TShape)(Object) new DelegatorDuplexChannel[/align]
[align=left] (this, (IDuplexChannel)innerChannel, "SEND");[/align]
[align=left] }[/align]
[align=left] if(typeof(TShape) == typeof(IOutputSessionChannel)) {[/align]
[align=left] return (TShape)(Object) new DelegatorOutputSessionChannel[/align]
[align=left] (this, (IOutputSessionChannel)innerChannel, "SEND");[/align]
[align=left] }[/align]
[align=left] if(typeof(TShape) == typeof(IRequestSessionChannel)) {[/align]
[align=left] return (TShape)(Object) new DelegatorRequestSessionChannel[/align]
[align=left] (this, (IRequestSessionChannel)innerChannel, "SEND");[/align]
[align=left] }[/align]
[align=left] if(typeof(TShape) == typeof(IDuplexSessionChannel)) {[/align]
[align=left] return (TShape)(Object) new DelegatorDuplexSessionChannel[/align]
[align=left] (this, (IDuplexSessionChannel)innerChannel, "SEND");[/align]
[align=left] }[/align]
[align=left] // cannot wrap this channel[/align]
[align=left] throw new ArgumentException(String.Format("invalid channel shape[/align]
[align=left] passed:{0}", innerChannel.GetType()));[/align]
[align=left] }[/align]
[align=left] // uses the _innerFactory member variable to build a channel[/align]
[align=left] // then wraps it and returns the wrapped channel[/align]
[align=left] protected override TShape OnCreateChannel(EndpointAddress address,[/align]
[align=left] Uri via) {[/align]
[align=left] // create and return the channel[/align]
[align=left] PrintHelper.Print(_consolePrefix, "OnCreateChannel");[/align]
[align=left] TShape innerChannel = this._innerFactory.CreateChannel(address, via);[/align]
[align=left] return WrapChannel(innerChannel);[/align]
[align=left] }[/align]
[align=left] protected override IAsyncResult OnBeginOpen(TimeSpan timeout,[/align]
[align=left] AsyncCallback callback,[/align]
[align=left] Object state) {[/align]
[align=left] PrintHelper.Print(_consolePrefix, "OnBeginChannel");[/align]
[align=left] return this._innerFactory.BeginOpen(timeout, callback, state);[/align]
[align=left] }[/align]
[align=left] protected override void OnAbort() {[/align]
[align=left] base.OnAbort();[/align]
[align=left] PrintHelper.Print(_consolePrefix, "OnAbort");[/align]
[align=left] }[/align]
[align=left] protected override void OnClose(TimeSpan timeout) {[/align]
[align=left] base.OnClose(timeout);[/align]
[align=left] PrintHelper.Print(_consolePrefix, "OnClose");[/align]
[align=left] }[/align]
[align=left] protected override void OnEndOpen(IAsyncResult result) {[/align]
[align=left] PrintHelper.Print(_consolePrefix, "OnEndOpen");[/align]
[align=left] this._innerFactory.EndOpen(result);[/align]
[align=left] }[/align]
[align=left] protected override void OnOpen(TimeSpan timeout) {[/align]
[align=left] PrintHelper.Print(_consolePrefix, "OnOpen");[/align]
[align=left] this._innerFactory.Open(timeout);[/align]
[align=left] }[/align]
[align=left] public override T GetProperty<T>() {[/align]
[align=left] PrintHelper.Print(_consolePrefix, "GetProperty<" + typeof(T).Name +[/align]
[align=left] ">");[/align]
[align=left] return this._innerFactory.GetProperty<T>();[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]定义上来看,DelegatorChannelFactory<TShape>与DelegatorChannelListener<TShape>很相似,它定义了一个私有的WrapChannel方法,可以把一个通道包装为特定的形状,然后返回。当然也定义了另外几个方法,这些方法可以把状态转换传递给成员变量innerFactory的。[/align]

本章小结

WCF类型通过通道工厂和通道侦听器来创建通道。通道侦听器负责侦听可用的连接。通道工厂和通道侦听器的架构模型与伯克利的Sockets API十分相似,和通道一样,通道工厂和通道侦听器也是在运行时组装到堆栈的,并且堆栈里的每个通道侦听器或通道工厂都负责创建一个通道。另外就是传输通道工厂或者通道侦听器必须位于堆栈的底部。此外,用户代码不能直接实例化通道侦听器和通道工厂。这些工作有BindingElement完成。Binding和BindingElement对象会在下一章里讲到,而且作为总结部分,你会看到我们定义的DelegatorChannel 通道、以及DelegatorChannelListener<TShape> 和DelegatorChannelFactory<TShape>类型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐