2009-01-23 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 InvokeAsyncCompletedEventArgs : AsyncCompletedEventArgs
309                 {
310                         internal InvokeAsyncCompletedEventArgs (object [] results, Exception error, bool cancelled, object userState)
311                                 : base (error, cancelled, userState)
312                         {
313                                 Results = results;
314                         }
315
316                         public object [] Results { get; private set; }
317                 }
318
319                 protected class ChannelBase<T> : IClientChannel, IOutputChannel, IRequestChannel where T : class
320                 {
321                         ClientBase<T> client;
322
323                         protected ChannelBase (ClientBase<T> client)
324                         {
325                                 this.client = client;
326                         }
327
328                         [MonoTODO]
329                         protected IAsyncResult BeginInvoke (string methodName, object [] args, AsyncCallback callback, object state)
330                         {
331                                 throw new NotImplementedException ();
332                         }
333
334                         [MonoTODO]
335                         protected object EndInvoke (string methodName, object [] args, IAsyncResult result)
336                         {
337                                 throw new NotImplementedException ();
338                         }
339
340                         #region ICommunicationObject
341
342                         IAsyncResult ICommunicationObject.BeginClose (AsyncCallback callback, object state)
343                         {
344                                 return client.InnerChannel.BeginClose (callback, state);
345                         }
346
347                         IAsyncResult ICommunicationObject.BeginClose (TimeSpan timeout, AsyncCallback callback, object state)
348                         {
349                                 return client.InnerChannel.BeginClose (timeout, callback, state);
350                         }
351
352                         void ICommunicationObject.Close ()
353                         {
354                                 client.InnerChannel.Close ();
355                         }
356
357                         void ICommunicationObject.Close (TimeSpan timeout)
358                         {
359                                 client.InnerChannel.Close (timeout);
360                         }
361
362                         IAsyncResult ICommunicationObject.BeginOpen (AsyncCallback callback, object state)
363                         {
364                                 return client.InnerChannel.BeginOpen (callback, state);
365                         }
366
367                         IAsyncResult ICommunicationObject.BeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
368                         {
369                                 return client.InnerChannel.BeginOpen (timeout, callback, state);
370                         }
371
372                         void ICommunicationObject.Open ()
373                         {
374                                 client.InnerChannel.Open ();
375                         }
376
377                         void ICommunicationObject.Open (TimeSpan timeout)
378                         {
379                                 client.InnerChannel.Open (timeout);
380                         }
381
382                         void ICommunicationObject.Abort ()
383                         {
384                                 client.InnerChannel.Abort ();
385                         }
386
387                         void ICommunicationObject.EndClose (IAsyncResult result)
388                         {
389                                 client.InnerChannel.EndClose (result);
390                         }
391
392                         void ICommunicationObject.EndOpen (IAsyncResult result)
393                         {
394                                 client.InnerChannel.EndOpen (result);
395                         }
396
397                         CommunicationState ICommunicationObject.State {
398                                 get { return client.InnerChannel.State; }
399                         }
400
401                         event EventHandler ICommunicationObject.Opened {
402                                 add { client.InnerChannel.Opened += value; }
403                                 remove { client.InnerChannel.Opened -= value; }
404                         }
405
406                         event EventHandler ICommunicationObject.Opening {
407                                 add { client.InnerChannel.Opening += value; }
408                                 remove { client.InnerChannel.Opening -= value; }
409                         }
410
411                         event EventHandler ICommunicationObject.Closed {
412                                 add { client.InnerChannel.Closed += value; }
413                                 remove { client.InnerChannel.Closed -= value; }
414                         }
415
416                         event EventHandler ICommunicationObject.Closing {
417                                 add { client.InnerChannel.Closing += value; }
418                                 remove { client.InnerChannel.Closing -= value; }
419                         }
420
421                         event EventHandler ICommunicationObject.Faulted {
422                                 add { client.InnerChannel.Faulted += value; }
423                                 remove { client.InnerChannel.Faulted -= value; }
424                         }
425
426                         #endregion
427
428                         #region IClientChannel
429
430                         public bool AllowInitializationUI {
431                                 get { return client.InnerChannel.AllowInitializationUI; }
432                                 set { client.InnerChannel.AllowInitializationUI = value; }
433                         }
434
435                         public bool DidInteractiveInitialization {
436                                 get { return client.InnerChannel.DidInteractiveInitialization; }
437                         }
438
439                         public Uri Via {
440                                 get { return client.InnerChannel.Via; }
441                         }
442
443                         public IAsyncResult BeginDisplayInitializationUI (
444                                 AsyncCallback callback, object state)
445                         {
446                                 return client.InnerChannel.BeginDisplayInitializationUI (callback, state);
447                         }
448
449                         public void EndDisplayInitializationUI (
450                                 IAsyncResult result)
451                         {
452                                 client.InnerChannel.EndDisplayInitializationUI (result);
453                         }
454
455                         public void DisplayInitializationUI ()
456                         {
457                                 client.InnerChannel.DisplayInitializationUI ();
458                         }
459
460                         public void Dispose ()
461                         {
462                                 client.InnerChannel.Dispose ();
463                         }
464
465                         public event EventHandler<UnknownMessageReceivedEventArgs> UnknownMessageReceived {
466                                 add { client.InnerChannel.UnknownMessageReceived += value; }
467                                 remove { client.InnerChannel.UnknownMessageReceived -= value; }
468                         }
469
470                         #endregion
471
472                         #region IContextChannel
473
474                         [MonoTODO]
475                         public bool AllowOutputBatching {
476                                 get { return client.InnerChannel.AllowOutputBatching; }
477
478                                 set { client.InnerChannel.AllowOutputBatching = value; }
479                         }
480
481                         [MonoTODO]
482                         public IInputSession InputSession {
483                                 get { return client.InnerChannel.InputSession; }
484                         }
485
486                         [MonoTODO]
487                         public EndpointAddress LocalAddress {
488                                 get { return client.InnerChannel.LocalAddress; }
489                         }
490
491                         [MonoTODO]
492                         public TimeSpan OperationTimeout {
493                                 get { return client.InnerChannel.OperationTimeout; }
494                                 set { client.InnerChannel.OperationTimeout = value; }
495                         }
496
497                         [MonoTODO]
498                         public IOutputSession OutputSession {
499                                 get { return client.InnerChannel.OutputSession; }
500                         }
501
502                         [MonoTODO]
503                         public EndpointAddress RemoteAddress {
504                                 get { return client.InnerChannel.RemoteAddress; }
505                         }
506
507                         [MonoTODO]
508                         public string SessionId {
509                                 get { return client.InnerChannel.SessionId; }
510                         }
511
512                         #endregion
513
514
515                         [MonoTODO]
516                         IAsyncResult IRequestChannel.BeginRequest (Message message, AsyncCallback callback, object state)
517                         {
518                                 throw new NotImplementedException ();
519                         }
520
521                         [MonoTODO]
522                         IAsyncResult IRequestChannel.BeginRequest (Message message, TimeSpan timeout, AsyncCallback callback, object state)
523                         {
524                                 throw new NotImplementedException ();
525                         }
526
527                         [MonoTODO]
528                         Message IRequestChannel.EndRequest (IAsyncResult result)
529                         {
530                                 throw new NotImplementedException ();
531                         }
532
533                         [MonoTODO]
534                         Message IRequestChannel.Request (Message message)
535                         {
536                                 throw new NotImplementedException ();
537                         }
538
539                         [MonoTODO]
540                         Message IRequestChannel.Request (Message message, TimeSpan timeout)
541                         {
542                                 throw new NotImplementedException ();
543                         }
544
545                         [MonoTODO]
546                         EndpointAddress IRequestChannel.RemoteAddress {
547                                 get { throw new NotImplementedException (); }
548                         }
549
550                         [MonoTODO]
551                         Uri IRequestChannel.Via {
552                                 get { throw new NotImplementedException (); }
553                         }
554
555                         [MonoTODO]
556                         IAsyncResult IOutputChannel.BeginSend (Message message, AsyncCallback callback, object state)
557                         {
558                                 throw new NotImplementedException ();
559                         }
560
561                         [MonoTODO]
562                         IAsyncResult IOutputChannel.BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
563                         {
564                                 throw new NotImplementedException ();
565                         }
566
567                         [MonoTODO]
568                         void IOutputChannel.EndSend (IAsyncResult result)
569                         {
570                                 throw new NotImplementedException ();
571                         }
572
573                         [MonoTODO]
574                         void IOutputChannel.Send (Message message)
575                         {
576                                 throw new NotImplementedException ();
577                         }
578
579                         [MonoTODO]
580                         void IOutputChannel.Send (Message message, TimeSpan timeout)
581                         {
582                                 throw new NotImplementedException ();
583                         }
584
585                         [MonoTODO]
586                         IExtensionCollection<IContextChannel> IExtensibleObject<IContextChannel>.Extensions {
587                                 get { return client.InnerChannel.Extensions; }
588                         }
589
590                         [MonoTODO]
591                         TProperty IChannel.GetProperty<TProperty> ()
592                         {
593                                 return client.InnerChannel.GetProperty<TProperty> ();
594                         }
595                 }
596 #endif
597         }
598 }