WCF的Binding模型之四:信道工厂(Channel Factory)

由于信道管理器在客户端和服务端所起的不同作用,分为信道监听器和信道工厂。和服务端的信道监听其相比,处于客户端的信道工厂显得简单。从名称就可以看得出来,信道工厂的作用就是单纯的创建用于消息发送的信道。我们先来看看与信道工厂相关的一些接口和基类的定义。

一、信道工厂相关的接口和基类

对于信道监听器,WCF定义了两个接口:IChannelListener和IChnnelListener<TChannel>。与之相对地,WCF也为信道工厂定义了两个接口:IChannelFactory和IChannelFactory<TChannel>。这两个接口定义了信道工厂最基本的功能和属性,下面是这两个接口的定义:

1: public interface IChannelFactory : ICommunicationObject
2: {
3:     // Methods
4:     T GetProperty<T>() where T : class;
5: }
6: public interface IChannelFactory<TChannel> : IChannelFactory, ICommunicationObject
7: {
8:     // Methods
9:     TChannel CreateChannel(EndpointAddress to);
0:     TChannel CreateChannel(EndpointAddress to, Uri via);
1: }

由于信道工厂的目的就是单纯的创建信道,所以IChannelFactory和IChannelFactory<TChannel>的定义显得格外简洁。两个重载的CreateChannel方法通过目的终结点的地址(to),以及在手工寻址下不同于目的终结点地址的另一个地址,该地址是消息实际会被发送的地址(via)。关于To和Via可以参考第二章关于物理地址和逻辑地址的部分。

除了上面的两个接口之外,WCF还定义分别是实现了它们的两个抽象基类:ChannelFactoryBase和ChannelFactoryBase<TChannel>。ChannelFactoryBase继承自所有信道管理器的基类:CnannelManagerBase,而ChannelManagerBase又继承自CommunicationObject,实现ICommunicationObject接口定义的基本的状态属性和状态转换功能。并且实现了接口IChannelFactory和ICommunicationObject。而ChannelFactoryBase<TChannel>继承自CnannelManagerBase,并且实现了接口:IChannelFactory<TChannel>, IChannelFactory和ICommunicationObject。一般地,范型类型TChannel为基于相应channel shape下客户端信道类型,比如IOutputChannel、IRequestChannel和IDuplexChannel。ChannelFactoryBase和ChannelFactoryBase<TChannel>的简单定义如下:

1: public abstract class ChannelFactoryBase : ChannelManagerBase, IChannelFactory, ICommunicationObject
2: {
3:     ......
4: }
5: public abstract class ChannelFactoryBase<TChannel> : ChannelFactoryBase, IChannelFactory<TChannel>, IChannelFactory, ICommunicationObject
6: {
7:     ......
8: } 

下面的类图简明直观的表述了WCF中关于信道工厂的体系结构。

二、案例演示:如何自定义信道工厂

在上一个案例中,我们创建了一个自定义的信道监听器:SimpleReplyChannelListner。该信道监听器用于在请求-回复消息交换模式下进行请求的监听。在本案例中,我们来创建与之相对的信道工厂:SimpleChannelFactory<TChannel>,用于请求-回复消息交换模式下进行用于请求发送信道的创建。由于SimpleChannelFactory<TChannel>的实现相对简单,将所有代码一并附上。

SimpleChannelFactory<TChannel>直接继承自抽象基类SimpleChannelFactoryBase<TChannel>。字段成员_innerChannelFactory表示信道工厂栈中后一个信道工厂对象,该成员在构造函数中通过传入的BindingContext对象的BuildInnerChannelFactory<TChannel>方法创建。OnCreateChannel是核心大方法,实现了真正的信道创建过程,在这里我们创建了我们自定义的信道:SimpleRequestChannel.。构建SimpleRequestChannel. 的InnerChannel通过­­­_innerChannelFactory的CreateChannel方法创建。对于其他的方法(OnOpen、OnBeginOpen和OnEndOpen),我们仅仅通过PrintHelper输出当前的方法名称,并调用­_innerChannelFactory相应的方法。  

1: public class SimpleChannelFactory<TChannel> : ChannelFactoryBase<TChannel>
2: {
3:     public IChannelFactory<TChannel> _innerChannelFactory;
4: 
5:     public SimpleChannelFactory(BindingContext context)
6:     {
7:         PrintHelper.Print(this, "SimpleChannelFactory");
8:         this._innerChannelFactory = context.BuildInnerChannelFactory<TChannel>();
9:     }
0: 
1:     protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
2:     {
3:         PrintHelper.Print(this, "OnCreateChannel");
4:         IRequestChannel innerChannel = this._innerChannelFactory.CreateChannel(address, via) as IRequestChannel;
5:         SimpleRequestChannel. channel = new SimpleRequestChannel.(this, innerChannel);
6:         return (TChannel)(object)channel;
7:     }
8: 
9:     protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
0:     {
1:         PrintHelper.Print(this, "OnBeginOpen");
2:         return this._innerChannelFactory.BeginOpen(timeout, callback, state);
3:     }
4: 
5:     protected override void OnEndOpen(IAsyncResult result)
6:     {
7:         PrintHelper.Print(this, "OnEndOpen");
8:         this._innerChannelFactory.EndOpen(result);
9:     }
0: 
1:     protected override void OnOpen(TimeSpan timeout)
2:     {
3:         PrintHelper.Print(this, "OnOpen");
4:         this._innerChannelFactory.Open(timeout);
5:     }
6: }

WCF中的绑定模型: [WCF中的Binding模型]之一: Binding模型简介 [WCF中的Binding模型]之二: 信道与信道栈(Channel and Channel Stack) [WCF中的Binding模型]之三:信道监听器(Channel Listener) [WCF中的Binding模型]之四:信道工厂(Channel Factory) [WCF中的Binding模型]之五:绑定元素(Binding Element) [WCF中的Binding模型]之六:从绑定元素认识系统预定义绑定

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏飞扬的花生

在ASP.MVC中使用Ajax

      Asp.net MVC 抛弃了Asp.net WebForm那种高度封装的控件,让我们跟底层的HTML有了更多的亲近。可以更自由、更灵活的去控制HT...

2139
来自专栏逸鹏说道

我这么玩Web Api(二)

数据验证,全局数据验证与单元测试 目录 一、模型状态 - ModelState 二、数据注解 - Data Annotations 三、自定义数据注解 四、全局...

5146
来自专栏Spark生态圈

[spark] Task成功执行的结果处理

在文章Task执行流程 中介绍了task是怎么被分配到executor上执行的,本文讲解task成功执行时将结果返回给driver的处理流程。

2194
来自专栏Android 开发学习

JsBridge 源码分析

1643
来自专栏逍遥剑客的游戏开发

OGRE中用到的设计模式

2207
来自专栏GreenLeaves

oracle 层次化查询(生成菜单树等)

1、简介:Oracle层次化查询是Oracle特有的功能实现,主要用于返回一个数据集,这个数据集存在树的关系(数据集中存在一个Pid记录着当前数据集某一条记录的...

2308
来自专栏菩提树下的杨过

silverlight动态读取txt文件/解析json数据/调用wcf示例

终于开始正式学习silverlight,虽然有点晚,但总算开始了,今天看了一下sdk,主要是想看下silverlight中如何动态调用数据,对于数据库的访问,s...

23110
来自专栏大内老A

通过一个模拟程序让你明白ASP.NET MVC是如何运行的

ASP.NET MVC的路由系统通过对HTTP请求的解析得到表示Controller、Action和其他相关的数据,并以此为依据激活Controller对象,调...

2886
来自专栏Java学习网

常见的 Java 错误及避免方法之第五集(每集10个错误后续持续发布)

当输入期间意外终止文件或流时,将抛出“EOFException”。 以下是抛出EOFException异常的一个示例,来自JavaBeat应用程序:

1423
来自专栏Java架构师学习

Zookeeper-watcher机制源码分析(二)

其大致流程如下   ① 通过传入的path(节点路径)从watchTable获取相应的watcher集合,进入②

1411

扫码关注云+社区

领取腾讯云代金券