一、信道工廠相關的接口和基類
對於信道監聽器,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);
- 10: TChannel CreateChannel(EndpointAddress to, Uri via);
- 11: }
除了上面的兩個接口之外,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: }
模型]之四:信道工廠(Channel Factory)_10966" src="/attachment.aspx?attachmentid=10966">
二、案例演示:如何自定義信道工廠
在上一個案例中,我們創建了一個自定義的信道監聽器: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: }
10:
11: protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
12: {
13: PrintHelper.Print(this, "OnCreateChannel");
14: IRequestChannel innerChannel = this._innerChannelFactory.CreateChannel(address, via) as IRequestChannel;
15: SimpleRequestChannel. channel = new SimpleRequestChannel.(this, innerChannel);
16: return (TChannel)(object)channel;
17: }
18:
19: protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
20: {
21: PrintHelper.Print(this, "OnBeginOpen");
22: return this._innerChannelFactory.BeginOpen(timeout, callback, state);
23: }
24:
25: protected override void OnEndOpen(IAsyncResult result)
26: {
27: PrintHelper.Print(this, "OnEndOpen");
28: this._innerChannelFactory.EndOpen(result);
29: }
30:
31: protected override void OnOpen(TimeSpan timeout)
32: {
33: PrintHelper.Print(this, "OnOpen");
34: this._innerChannelFactory.Open(timeout);
35: }
36: }