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

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

对于信道监听器,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模型]之六:从绑定元素认识系统预定义绑定

WCF的Binding模型之四:信道工厂(Channel Factory)的更多相关文章

  1. WCF信道工厂Channel Factory

    ChannelFactory<TChannel> 类 一个创建不同类型通道的工厂,客户端使用这些通道将消息发送到不同配置的服务终结点. 命名空间: System.ServiceModel ...

  2. (二)WCF的Binding模型

    上篇博客对WCF中的基础知识进行了介绍,先从概念上知道了WCF的一些理论,在abc模型中B是Binding,WCF为我们提供了多种绑定机制,我们先从了解各种绑定机制开始,只有知道之后才能在实践中更好的 ...

  3. WCF编程系列(七)信道及信道工厂

    WCF编程系列(七)信道及信道工厂   信道及信道栈 前面已经提及过,WCF中客户端与服务端的交互都是通过消息来进行的.消息从客户端传送到服务端会经过多个处理动作,在WCF编程模型中,这些动作是按层 ...

  4. I/O模型之四:Java 浅析I/O模型(BIO、NIO、AIO、Reactor、Proactor)

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

  5. 工厂模式(Factory Patter)

    1.工厂模式简介 工厂模式属于创建型模式,是专门用来创建对象的模式,抽象了实例化的过程.工厂模式分为 : 工厂方法模式.抽象工厂模式. 在学习工厂方法模式.抽象工厂之前,首先先要了解一下简单工厂模式, ...

  6. Spring 通过工厂方法(Factory Method)来配置bean

    Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...

  7. 设计模式(一)工厂模式Factory(创建型)

    设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.可是在一些情况下, new操作符直接生成对象会带来一些问题. ...

  8. 设计模式(一)工厂模式Factory(创建类型)

    设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.可是在一些情况下, new操作符直接生成对象会带来一些问题. ...

  9. 工厂模式(Factory)和抽象工厂模式(Abstract Factory)

    一.工厂模式(Factory):通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的,工厂方法让类的实例化推迟到子类 (1)涉及角色:抽象产品,具体产品,抽象创建者,具体创建者.     ...

随机推荐

  1. BaseAdapter的优化

    传统的 package cct.commonadapter.bean; import android.content.Context; import android.view.LayoutInflat ...

  2. iOS截取特定的字符串(正则匹配)

    有时候我们会有需求从一个字符串中截取其他的字符串,根据情况的不同,我们来分析几种方法~~ 一. 固定长度字符串中截取固定位置长度的字符串 // 这是比较简单的一种情况:比如截取手机号的后4位 let ...

  3. jQuery 点击查看 收起

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. CHECKPOINT - 强制一个事务日志检查点

    SYNOPSIS CHECKPOINT DESCRIPTION 描述 预写式日志(Write-Ahead Logging (WAL))缺省时在事务日志中每隔一段时间放一个检查点. (要调整这个原子化的 ...

  5. Vue之x-template(1)

    今天,我们来讲一个比较有趣的一个功能吧 先来看一段代码示例: <html> <head> <meta charset="utf-8"> < ...

  6. powerdesigner连接MySQL数据库时出现Non SQL Error : Could not load class com.mysql.jdbc.Driver

    Non SQL Error : Could not load class com.mysql.jdbc.Driver 这是因为powerdesigner 无法找到驱动所产生的 解决办法是:配置系统的c ...

  7. ajax 分页点击数据缓存

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 为了安全请不要随意在页面中设置validateRequest="false"

    为了安全请不要随意在页面中设置validateRequest="false" 分类: ASP.NET2009-04-12 17:24 531人阅读 评论(0) 收藏 举报 asp. ...

  9. vue全选与反选以及通过使用如何filter删除数据

    在vue学习经常遇到的一些基本问题,下面是购物车里面的部分功能,分享给初学者,直接上源码: <!DOCTYPE html><html> <head> <met ...

  10. HDU - 4544 湫湫系列故事——消灭兔子(优先队列+贪心)

    题目: 最近,减肥失败的湫湫为发泄心中郁闷,在玩一个消灭免子的游戏. 游戏规则很简单,用箭杀死免子即可. 箭是一种消耗品,已知有M种不同类型的箭可以选择,并且每种箭都会对兔子造成伤害,对应的伤害值分别 ...