1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 
5 namespace System.ServiceModel.Dispatcher
6 {
7     using System;
8     using System.ServiceModel.Channels;
9 
10     static class ListenerBinder
11     {
GetBinder(IChannelListener listener, MessageVersion messageVersion)12         internal static IListenerBinder GetBinder(IChannelListener listener, MessageVersion messageVersion)
13         {
14             IChannelListener<IInputChannel> input = listener as IChannelListener<IInputChannel>;
15             if (input != null)
16                 return new InputListenerBinder(input, messageVersion);
17 
18             IChannelListener<IInputSessionChannel> inputSession = listener as IChannelListener<IInputSessionChannel>;
19             if (inputSession != null)
20                 return new InputSessionListenerBinder(inputSession, messageVersion);
21 
22             IChannelListener<IReplyChannel> reply = listener as IChannelListener<IReplyChannel>;
23             if (reply != null)
24                 return new ReplyListenerBinder(reply, messageVersion);
25 
26             IChannelListener<IReplySessionChannel> replySession = listener as IChannelListener<IReplySessionChannel>;
27             if (replySession != null)
28                 return new ReplySessionListenerBinder(replySession, messageVersion);
29 
30             IChannelListener<IDuplexChannel> duplex = listener as IChannelListener<IDuplexChannel>;
31             if (duplex != null)
32                 return new DuplexListenerBinder(duplex, messageVersion);
33 
34             IChannelListener<IDuplexSessionChannel> duplexSession = listener as IChannelListener<IDuplexSessionChannel>;
35             if (duplexSession != null)
36                 return new DuplexSessionListenerBinder(duplexSession, messageVersion);
37 
38             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnknownListenerType1, listener.Uri.AbsoluteUri)));
39         }
40 
41         // ------------------------------------------------------------------------------------------------------------
42         // Listener Binders
43 
44         class DuplexListenerBinder : IListenerBinder
45         {
46             IRequestReplyCorrelator correlator;
47             IChannelListener<IDuplexChannel> listener;
48             MessageVersion messageVersion;
49 
DuplexListenerBinder(IChannelListener<IDuplexChannel> listener, MessageVersion messageVersion)50             internal DuplexListenerBinder(IChannelListener<IDuplexChannel> listener, MessageVersion messageVersion)
51             {
52                 this.correlator = new RequestReplyCorrelator();
53                 this.listener = listener;
54                 this.messageVersion = messageVersion;
55             }
56 
57             public IChannelListener Listener
58             {
59                 get { return this.listener; }
60             }
61 
62             public MessageVersion MessageVersion
63             {
64                 get { return this.messageVersion; }
65             }
66 
Accept(TimeSpan timeout)67             public IChannelBinder Accept(TimeSpan timeout)
68             {
69                 IDuplexChannel channel = this.listener.AcceptChannel(timeout);
70                 if (channel == null)
71                     return null;
72 
73                 return new DuplexChannelBinder(channel, this.correlator, this.listener.Uri);
74             }
75 
BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)76             public IAsyncResult BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)
77             {
78                 return this.listener.BeginAcceptChannel(timeout, callback, state);
79             }
80 
EndAccept(IAsyncResult result)81             public IChannelBinder EndAccept(IAsyncResult result)
82             {
83                 IDuplexChannel channel = this.listener.EndAcceptChannel(result);
84                 if (channel == null)
85                     return null;
86 
87                 return new DuplexChannelBinder(channel, this.correlator, this.listener.Uri);
88             }
89         }
90 
91         class DuplexSessionListenerBinder : IListenerBinder
92         {
93             IRequestReplyCorrelator correlator;
94             IChannelListener<IDuplexSessionChannel> listener;
95             MessageVersion messageVersion;
96 
DuplexSessionListenerBinder(IChannelListener<IDuplexSessionChannel> listener, MessageVersion messageVersion)97             internal DuplexSessionListenerBinder(IChannelListener<IDuplexSessionChannel> listener, MessageVersion messageVersion)
98             {
99                 this.correlator = new RequestReplyCorrelator();
100                 this.listener = listener;
101                 this.messageVersion = messageVersion;
102             }
103 
104             public IChannelListener Listener
105             {
106                 get { return this.listener; }
107             }
108 
109             public MessageVersion MessageVersion
110             {
111                 get { return this.messageVersion; }
112             }
113 
Accept(TimeSpan timeout)114             public IChannelBinder Accept(TimeSpan timeout)
115             {
116                 IDuplexSessionChannel channel = this.listener.AcceptChannel(timeout);
117                 if (channel == null)
118                     return null;
119 
120                 return new DuplexChannelBinder(channel, this.correlator, this.listener.Uri);
121             }
122 
BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)123             public IAsyncResult BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)
124             {
125                 return this.listener.BeginAcceptChannel(timeout, callback, state);
126             }
127 
EndAccept(IAsyncResult result)128             public IChannelBinder EndAccept(IAsyncResult result)
129             {
130                 IDuplexSessionChannel channel = this.listener.EndAcceptChannel(result);
131                 if (channel == null)
132                     return null;
133 
134                 return new DuplexChannelBinder(channel, this.correlator, this.listener.Uri);
135             }
136         }
137 
138         class InputListenerBinder : IListenerBinder
139         {
140             IChannelListener<IInputChannel> listener;
141             MessageVersion messageVersion;
142 
InputListenerBinder(IChannelListener<IInputChannel> listener, MessageVersion messageVersion)143             internal InputListenerBinder(IChannelListener<IInputChannel> listener, MessageVersion messageVersion)
144             {
145                 this.listener = listener;
146                 this.messageVersion = messageVersion;
147             }
148 
149             public IChannelListener Listener
150             {
151                 get { return this.listener; }
152             }
153 
154             public MessageVersion MessageVersion
155             {
156                 get { return this.messageVersion; }
157             }
158 
Accept(TimeSpan timeout)159             public IChannelBinder Accept(TimeSpan timeout)
160             {
161                 IInputChannel channel = this.listener.AcceptChannel(timeout);
162                 if (channel == null)
163                     return null;
164 
165                 return new InputChannelBinder(channel, this.listener.Uri);
166             }
167 
BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)168             public IAsyncResult BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)
169             {
170                 return this.listener.BeginAcceptChannel(timeout, callback, state);
171             }
172 
EndAccept(IAsyncResult result)173             public IChannelBinder EndAccept(IAsyncResult result)
174             {
175                 IInputChannel channel = this.listener.EndAcceptChannel(result);
176                 if (channel == null)
177                     return null;
178 
179                 return new InputChannelBinder(channel, this.listener.Uri);
180             }
181         }
182 
183         class InputSessionListenerBinder : IListenerBinder
184         {
185             IChannelListener<IInputSessionChannel> listener;
186             MessageVersion messageVersion;
187 
InputSessionListenerBinder(IChannelListener<IInputSessionChannel> listener, MessageVersion messageVersion)188             internal InputSessionListenerBinder(IChannelListener<IInputSessionChannel> listener, MessageVersion messageVersion)
189             {
190                 this.listener = listener;
191                 this.messageVersion = messageVersion;
192             }
193 
194             public IChannelListener Listener
195             {
196                 get { return this.listener; }
197             }
198 
199             public MessageVersion MessageVersion
200             {
201                 get { return this.messageVersion; }
202             }
203 
Accept(TimeSpan timeout)204             public IChannelBinder Accept(TimeSpan timeout)
205             {
206                 IInputSessionChannel channel = this.listener.AcceptChannel(timeout);
207                 if (null == channel)
208                     return null;
209 
210                 return new InputChannelBinder(channel, this.listener.Uri);
211             }
212 
BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)213             public IAsyncResult BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)
214             {
215                 return this.listener.BeginAcceptChannel(timeout, callback, state);
216             }
217 
EndAccept(IAsyncResult result)218             public IChannelBinder EndAccept(IAsyncResult result)
219             {
220                 IInputSessionChannel channel = this.listener.EndAcceptChannel(result);
221                 if (channel == null)
222                     return null;
223 
224                 return new InputChannelBinder(channel, this.listener.Uri);
225             }
226         }
227 
228         class ReplyListenerBinder : IListenerBinder
229         {
230             IChannelListener<IReplyChannel> listener;
231             MessageVersion messageVersion;
232 
ReplyListenerBinder(IChannelListener<IReplyChannel> listener, MessageVersion messageVersion)233             internal ReplyListenerBinder(IChannelListener<IReplyChannel> listener, MessageVersion messageVersion)
234             {
235                 this.listener = listener;
236                 this.messageVersion = messageVersion;
237             }
238 
239             public IChannelListener Listener
240             {
241                 get { return this.listener; }
242             }
243 
244             public MessageVersion MessageVersion
245             {
246                 get { return this.messageVersion; }
247             }
248 
Accept(TimeSpan timeout)249             public IChannelBinder Accept(TimeSpan timeout)
250             {
251                 IReplyChannel channel = this.listener.AcceptChannel(timeout);
252                 if (channel == null)
253                     return null;
254 
255                 return new ReplyChannelBinder(channel, listener.Uri);
256             }
257 
BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)258             public IAsyncResult BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)
259             {
260                 return this.listener.BeginAcceptChannel(timeout, callback, state);
261             }
262 
EndAccept(IAsyncResult result)263             public IChannelBinder EndAccept(IAsyncResult result)
264             {
265                 IReplyChannel channel = this.listener.EndAcceptChannel(result);
266                 if (channel == null)
267                     return null;
268 
269                 return new ReplyChannelBinder(channel, listener.Uri);
270             }
271         }
272 
273         class ReplySessionListenerBinder : IListenerBinder
274         {
275             IChannelListener<IReplySessionChannel> listener;
276             MessageVersion messageVersion;
277 
ReplySessionListenerBinder(IChannelListener<IReplySessionChannel> listener, MessageVersion messageVersion)278             internal ReplySessionListenerBinder(IChannelListener<IReplySessionChannel> listener, MessageVersion messageVersion)
279             {
280                 this.listener = listener;
281                 this.messageVersion = messageVersion;
282             }
283 
284             public IChannelListener Listener
285             {
286                 get { return this.listener; }
287             }
288 
289             public MessageVersion MessageVersion
290             {
291                 get { return this.messageVersion; }
292             }
293 
Accept(TimeSpan timeout)294             public IChannelBinder Accept(TimeSpan timeout)
295             {
296                 IReplySessionChannel channel = this.listener.AcceptChannel(timeout);
297                 if (channel == null)
298                     return null;
299 
300                 return new ReplyChannelBinder(channel, listener.Uri);
301             }
302 
BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)303             public IAsyncResult BeginAccept(TimeSpan timeout, AsyncCallback callback, object state)
304             {
305                 return this.listener.BeginAcceptChannel(timeout, callback, state);
306             }
307 
EndAccept(IAsyncResult result)308             public IChannelBinder EndAccept(IAsyncResult result)
309             {
310                 IReplySessionChannel channel = this.listener.EndAcceptChannel(result);
311                 if (channel == null)
312                     return null;
313 
314                 return new ReplyChannelBinder(channel, listener.Uri);
315             }
316         }
317     }
318 }
319