2009-01-22 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel / ClientBase.cs
1 //
2 // generic ClientBase.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005-2006 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.ComponentModel;
31 using System.ServiceModel.Channels;
32 using System.ServiceModel.Description;
33 using System.ServiceModel.Dispatcher;
34 using System.Threading;
35
36 namespace System.ServiceModel
37 {
38         [MonoTODO ("It somehow rejects classes, but dunno how we can do that besides our code level.")]
39         public abstract class ClientBase<TChannel>
40                 : IDisposable, ICommunicationObject
41         {
42                 static InstanceContext initialContxt = new InstanceContext (null);
43
44                 ChannelFactory<TChannel> factory;
45                 ClientRuntimeChannel inner_channel;
46                 CommunicationState state;
47
48                 protected delegate IAsyncResult BeginOperationDelegate (object[] inValues, AsyncCallback asyncCallback, object state);
49                 protected delegate object[] EndOperationDelegate (IAsyncResult result);
50
51                 protected ClientBase ()
52                         : this (initialContxt)
53                 {
54                 }
55
56                 protected ClientBase (string endpointConfigurationName)
57                         : this (initialContxt, endpointConfigurationName)
58                 {
59                 }
60
61                 protected ClientBase (Binding binding, EndpointAddress remoteAddress)
62                         : this (initialContxt, binding, remoteAddress)
63                 {
64                 }
65
66                 protected ClientBase (string endpointConfigurationName, EndpointAddress remoteAddress)
67                         : this (initialContxt, endpointConfigurationName, remoteAddress)
68                 {
69                 }
70
71                 protected ClientBase (string endpointConfigurationName, string remoteAddress)
72                         : this (initialContxt, endpointConfigurationName, remoteAddress)
73                 {
74                 }
75
76                 protected ClientBase (InstanceContext instance)
77                         : this (instance, "*")
78                 {
79                 }
80
81                 protected ClientBase (InstanceContext instance, string endpointConfigurationName)
82                 {
83                         if (instance == null)
84                                 throw new ArgumentNullException ("instanceContext");
85                         if (endpointConfigurationName == null)
86                                 throw new ArgumentNullException ("endpointConfigurationName");
87
88                         Initialize (instance, endpointConfigurationName, null);
89                 }
90
91                 protected ClientBase (InstanceContext instance,
92                         string endpointConfigurationName, EndpointAddress remoteAddress)
93                 {
94                         if (instance == null)
95                                 throw new ArgumentNullException ("instanceContext");
96                         if (endpointConfigurationName == null)
97                                 throw new ArgumentNullException ("endpointConfigurationName");
98                         if (remoteAddress == null)
99                                 throw new ArgumentNullException ("remoteAddress");
100
101                         Initialize (instance, endpointConfigurationName, remoteAddress);
102                 }
103
104                 protected ClientBase (InstanceContext instance,
105                         string endpointConfigurationName, string remoteAddress)
106                 {
107                         if (instance == null)
108                                 throw new ArgumentNullException ("instanceContext");
109                         if (remoteAddress == null)
110                                 throw new ArgumentNullException ("endpointAddress");
111                         if (endpointConfigurationName == null)
112                                 throw new ArgumentNullException ("endpointConfigurationName");
113
114                         Initialize (instance, endpointConfigurationName, new EndpointAddress (remoteAddress));
115                 }
116
117                 protected ClientBase (InstanceContext instance,
118                         Binding binding, EndpointAddress remoteAddress)
119                 {
120                         if (instance == null)
121                                 throw new ArgumentNullException ("instanceContext");
122                         if (binding == null)
123                                 throw new ArgumentNullException ("binding");
124                         if (remoteAddress == null)
125                                 throw new ArgumentNullException ("remoteAddress");
126
127                         Initialize (instance, binding, remoteAddress);
128                 }
129
130                 void Initialize (InstanceContext instance,
131                         string endpointConfigurationName, EndpointAddress remoteAddress)
132                 {
133                         factory = new ChannelFactory<TChannel> (endpointConfigurationName, remoteAddress);
134                 }
135
136                 void Initialize (InstanceContext instance,
137                         Binding binding, EndpointAddress remoteAddress)
138                 {
139                         factory = new ChannelFactory<TChannel> (binding, remoteAddress);
140                 }
141
142                 public ChannelFactory<TChannel> ChannelFactory {
143                         get { return factory; }
144                 }
145
146 #if !NET_2_1
147                 public ClientCredentials ClientCredentials {
148                         get { return ChannelFactory.Credentials; }
149                 }
150 #endif
151
152                 public ServiceEndpoint Endpoint {
153                         get { return factory.Endpoint; }
154                 }
155
156                 public IClientChannel InnerChannel {
157                         get {
158                                 if (inner_channel == null)
159                                         inner_channel = (ClientRuntimeChannel) (object) factory.CreateChannel ();
160                                 return inner_channel;
161                         }
162                 }
163
164                 protected TChannel Channel {
165                         get { return (TChannel) (object) InnerChannel; }
166                 }
167
168                 public CommunicationState State {
169                         get { return InnerChannel.State; }
170                 }
171
172                 public void Abort ()
173                 {
174                         InnerChannel.Abort ();
175                 }
176
177                 public void Close ()
178                 {
179                         InnerChannel.Close ();
180                 }
181
182                 public void DisplayInitializationUI ()
183                 {
184                         InnerChannel.DisplayInitializationUI ();
185                 }
186
187 #if NET_2_1
188                 IAsyncResult delegate_async;
189
190                 protected void InvokeAsync (BeginOperationDelegate beginOperationDelegate,
191                         object [] inValues, EndOperationDelegate endOperationDelegate,
192                         SendOrPostCallback operationCompletedCallback, object userState)
193                 {
194                         if (beginOperationDelegate == null)
195                                 throw new ArgumentNullException ("beginOperationDelegate");
196                         if (endOperationDelegate == null)
197                                 throw new ArgumentNullException ("endOperationDelegate");
198                         if (delegate_async != null)
199                                 throw new InvalidOperationException ("Another async operation is in progress");
200
201                         var bw = new BackgroundWorker ();
202                         bw.DoWork += delegate (object o, DoWorkEventArgs e) {
203                                 delegate_async = beginOperationDelegate (inValues, null, userState);
204                         };
205                         bw.RunWorkerCompleted += delegate (object o, RunWorkerCompletedEventArgs e) {
206                                 var ret = endOperationDelegate (delegate_async);
207                                 if (operationCompletedCallback != null)
208                                         operationCompletedCallback (ret);
209                                 delegate_async = null;
210                         };
211                         bw.RunWorkerAsync ();
212                 }
213 #endif
214                 
215                 void IDisposable.Dispose ()
216                 {
217                         Close ();
218                 }
219
220                 protected virtual TChannel CreateChannel ()
221                 {
222                         return ChannelFactory.CreateChannel ();
223                 }
224
225                 public void Open ()
226                 {
227                         InnerChannel.Open ();
228                 }
229
230                 #region ICommunicationObject implementation
231
232                 [MonoTODO]
233                 IAsyncResult ICommunicationObject.BeginOpen (
234                         AsyncCallback callback, object state)
235                 {
236                         return InnerChannel.BeginOpen (callback, state);
237                 }
238
239                 [MonoTODO]
240                 IAsyncResult ICommunicationObject.BeginOpen (
241                         TimeSpan timeout, AsyncCallback callback, object state)
242                 {
243                         return InnerChannel.BeginOpen (timeout, callback, state);
244                 }
245
246                 [MonoTODO]
247                 void ICommunicationObject.EndOpen (IAsyncResult result)
248                 {
249                         InnerChannel.EndOpen (result);
250                 }
251
252                 [MonoTODO]
253                 IAsyncResult ICommunicationObject.BeginClose (
254                         AsyncCallback callback, object state)
255                 {
256                         return InnerChannel.BeginClose (callback, state);
257                 }
258
259                 [MonoTODO]
260                 IAsyncResult ICommunicationObject.BeginClose (
261                         TimeSpan timeout, AsyncCallback callback, object state)
262                 {
263                         return InnerChannel.BeginClose (timeout, callback, state);
264                 }
265
266                 [MonoTODO]
267                 void ICommunicationObject.EndClose (IAsyncResult result)
268                 {
269                         InnerChannel.EndClose (result);
270                 }
271
272                 [MonoTODO]
273                 void ICommunicationObject.Close (TimeSpan timeout)
274                 {
275                         InnerChannel.Close (timeout);
276                 }
277
278                 [MonoTODO]
279                 void ICommunicationObject.Open (TimeSpan timeout)
280                 {
281                         InnerChannel.Open (timeout);
282                 }
283
284                 event EventHandler ICommunicationObject.Opening {
285                         add { InnerChannel.Opening += value; }
286                         remove { InnerChannel.Opening -= value; }
287                 }
288                 event EventHandler ICommunicationObject.Opened {
289                         add { InnerChannel.Opened += value; }
290                         remove { InnerChannel.Opened -= value; }
291                 }
292                 event EventHandler ICommunicationObject.Closing {
293                         add { InnerChannel.Closing += value; }
294                         remove { InnerChannel.Closing -= value; }
295                 }
296                 event EventHandler ICommunicationObject.Closed {
297                         add { InnerChannel.Closed += value; }
298                         remove { InnerChannel.Closed -= value; }
299                 }
300                 event EventHandler ICommunicationObject.Faulted {
301                         add { InnerChannel.Faulted += value; }
302                         remove { InnerChannel.Faulted -= value; }
303                 }
304
305                 #endregion
306
307 #if NET_2_1
308                 protected class ChannelBase<T> : IClientChannel, IOutputChannel, IRequestChannel where T : class
309                 {
310                         ClientBase<T> client;
311
312                         protected ChannelBase (ClientBase<T> client)
313                         {
314                                 this.client = client;
315                         }
316
317                         [MonoTODO]
318                         protected IAsyncResult BeginInvoke (string methodName, object [] args, AsyncCallback callback, object state)
319                         {
320                                 throw new NotImplementedException ();
321                         }
322
323                         [MonoTODO]
324                         protected object EndInvoke (string methodName, object [] args, IAsyncResult result)
325                         {
326                                 throw new NotImplementedException ();
327                         }
328
329                         #region ICommunicationObject
330
331                         IAsyncResult ICommunicationObject.BeginClose (AsyncCallback callback, object state)
332                         {
333                                 return client.InnerChannel.BeginClose (callback, state);
334                         }
335
336                         IAsyncResult ICommunicationObject.BeginClose (TimeSpan timeout, AsyncCallback callback, object state)
337                         {
338                                 return client.InnerChannel.BeginClose (timeout, callback, state);
339                         }
340
341                         void ICommunicationObject.Close ()
342                         {
343                                 client.InnerChannel.Close ();
344                         }
345
346                         void ICommunicationObject.Close (TimeSpan timeout)
347                         {
348                                 client.InnerChannel.Close (timeout);
349                         }
350
351                         IAsyncResult ICommunicationObject.BeginOpen (AsyncCallback callback, object state)
352                         {
353                                 return client.InnerChannel.BeginOpen (callback, state);
354                         }
355
356                         IAsyncResult ICommunicationObject.BeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
357                         {
358                                 return client.InnerChannel.BeginOpen (timeout, callback, state);
359                         }
360
361                         void ICommunicationObject.Open ()
362                         {
363                                 client.InnerChannel.Open ();
364                         }
365
366                         void ICommunicationObject.Open (TimeSpan timeout)
367                         {
368                                 client.InnerChannel.Open (timeout);
369                         }
370
371                         void ICommunicationObject.Abort ()
372                         {
373                                 client.InnerChannel.Abort ();
374                         }
375
376                         void ICommunicationObject.EndClose (IAsyncResult result)
377                         {
378                                 client.InnerChannel.EndClose (result);
379                         }
380
381                         void ICommunicationObject.EndOpen (IAsyncResult result)
382                         {
383                                 client.InnerChannel.EndOpen (result);
384                         }
385
386                         CommunicationState ICommunicationObject.State {
387                                 get { return client.InnerChannel.State; }
388                         }
389
390                         event EventHandler ICommunicationObject.Opened {
391                                 add { client.InnerChannel.Opened += value; }
392                                 remove { client.InnerChannel.Opened -= value; }
393                         }
394
395                         event EventHandler ICommunicationObject.Opening {
396                                 add { client.InnerChannel.Opening += value; }
397                                 remove { client.InnerChannel.Opening -= value; }
398                         }
399
400                         event EventHandler ICommunicationObject.Closed {
401                                 add { client.InnerChannel.Closed += value; }
402                                 remove { client.InnerChannel.Closed -= value; }
403                         }
404
405                         event EventHandler ICommunicationObject.Closing {
406                                 add { client.InnerChannel.Closing += value; }
407                                 remove { client.InnerChannel.Closing -= value; }
408                         }
409
410                         event EventHandler ICommunicationObject.Faulted {
411                                 add { client.InnerChannel.Faulted += value; }
412                                 remove { client.InnerChannel.Faulted -= value; }
413                         }
414
415                         #endregion
416
417                         #region IClientChannel
418
419                         public bool AllowInitializationUI {
420                                 get { return client.InnerChannel.AllowInitializationUI; }
421                                 set { client.InnerChannel.AllowInitializationUI = value; }
422                         }
423
424                         public bool DidInteractiveInitialization {
425                                 get { return client.InnerChannel.DidInteractiveInitialization; }
426                         }
427
428                         public Uri Via {
429                                 get { return client.InnerChannel.Via; }
430                         }
431
432                         public IAsyncResult BeginDisplayInitializationUI (
433                                 AsyncCallback callback, object state)
434                         {
435                                 return client.InnerChannel.BeginDisplayInitializationUI (callback, state);
436                         }
437
438                         public void EndDisplayInitializationUI (
439                                 IAsyncResult result)
440                         {
441                                 client.InnerChannel.EndDisplayInitializationUI (result);
442                         }
443
444                         public void DisplayInitializationUI ()
445                         {
446                                 client.InnerChannel.DisplayInitializationUI ();
447                         }
448
449                         public void Dispose ()
450                         {
451                                 client.InnerChannel.Dispose ();
452                         }
453
454                         public event EventHandler<UnknownMessageReceivedEventArgs> UnknownMessageReceived {
455                                 add { client.InnerChannel.UnknownMessageReceived += value; }
456                                 remove { client.InnerChannel.UnknownMessageReceived -= value; }
457                         }
458
459                         #endregion
460
461                         #region IContextChannel
462
463                         [MonoTODO]
464                         public bool AllowOutputBatching {
465                                 get { return client.InnerChannel.AllowOutputBatching; }
466
467                                 set { client.InnerChannel.AllowOutputBatching = value; }
468                         }
469
470                         [MonoTODO]
471                         public IInputSession InputSession {
472                                 get { return client.InnerChannel.InputSession; }
473                         }
474
475                         [MonoTODO]
476                         public EndpointAddress LocalAddress {
477                                 get { return client.InnerChannel.LocalAddress; }
478                         }
479
480                         [MonoTODO]
481                         public TimeSpan OperationTimeout {
482                                 get { return client.InnerChannel.OperationTimeout; }
483                                 set { client.InnerChannel.OperationTimeout = value; }
484                         }
485
486                         [MonoTODO]
487                         public IOutputSession OutputSession {
488                                 get { return client.InnerChannel.OutputSession; }
489                         }
490
491                         [MonoTODO]
492                         public EndpointAddress RemoteAddress {
493                                 get { return client.InnerChannel.RemoteAddress; }
494                         }
495
496                         [MonoTODO]
497                         public string SessionId {
498                                 get { return client.InnerChannel.SessionId; }
499                         }
500
501                         #endregion
502
503
504                         [MonoTODO]
505                         IAsyncResult IRequestChannel.BeginRequest (Message message, AsyncCallback callback, object state)
506                         {
507                                 throw new NotImplementedException ();
508                         }
509
510                         [MonoTODO]
511                         IAsyncResult IRequestChannel.BeginRequest (Message message, TimeSpan timeout, AsyncCallback callback, object state)
512                         {
513                                 throw new NotImplementedException ();
514                         }
515
516                         [MonoTODO]
517                         Message IRequestChannel.EndRequest (IAsyncResult result)
518                         {
519                                 throw new NotImplementedException ();
520                         }
521
522                         [MonoTODO]
523                         Message IRequestChannel.Request (Message message)
524                         {
525                                 throw new NotImplementedException ();
526                         }
527
528                         [MonoTODO]
529                         Message IRequestChannel.Request (Message message, TimeSpan timeout)
530                         {
531                                 throw new NotImplementedException ();
532                         }
533
534                         [MonoTODO]
535                         EndpointAddress IRequestChannel.RemoteAddress {
536                                 get { throw new NotImplementedException (); }
537                         }
538
539                         [MonoTODO]
540                         Uri IRequestChannel.Via {
541                                 get { throw new NotImplementedException (); }
542                         }
543
544                         [MonoTODO]
545                         IAsyncResult IOutputChannel.BeginSend (Message message, AsyncCallback callback, object state)
546                         {
547                                 throw new NotImplementedException ();
548                         }
549
550                         [MonoTODO]
551                         IAsyncResult IOutputChannel.BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
552                         {
553                                 throw new NotImplementedException ();
554                         }
555
556                         [MonoTODO]
557                         void IOutputChannel.EndSend (IAsyncResult result)
558                         {
559                                 throw new NotImplementedException ();
560                         }
561
562                         [MonoTODO]
563                         void IOutputChannel.Send (Message message)
564                         {
565                                 throw new NotImplementedException ();
566                         }
567
568                         [MonoTODO]
569                         void IOutputChannel.Send (Message message, TimeSpan timeout)
570                         {
571                                 throw new NotImplementedException ();
572                         }
573
574                         [MonoTODO]
575                         IExtensionCollection<IContextChannel> IExtensibleObject<IContextChannel>.Extensions {
576                                 get { return client.InnerChannel.Extensions; }
577                         }
578
579                         [MonoTODO]
580                         TProperty IChannel.GetProperty<TProperty> ()
581                         {
582                                 return client.InnerChannel.GetProperty<TProperty> ();
583                         }
584                 }
585 #endif
586         }
587 }