Merge pull request #4542 from lateralusX/jlorenss/win-fix-unwind-tramp-reg-aot
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel / DuplexChannelFactory.cs
1 //
2 // DuplexChannelFactory.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //      Marcos Cobena (marcoscobena@gmail.com)
7 //
8 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
9 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 // 
30
31 using System;
32 using System.Collections.ObjectModel;
33 using System.ServiceModel.Channels;
34 using System.ServiceModel.Description;
35 using System.ServiceModel.Dispatcher;
36 using System.ServiceModel.MonoInternal;
37
38 namespace System.ServiceModel
39 {
40         public class DuplexChannelFactory<TChannel> : ChannelFactory<TChannel>
41         {
42                 InstanceContext callback_instance;
43                 Type callback_instance_type;
44
45                 public DuplexChannelFactory (Type callbackInstanceType)
46                         : base ()
47                 {
48                         callback_instance_type = callbackInstanceType;
49                 }
50
51                 public DuplexChannelFactory (Type callbackInstanceType,
52                         string endpointConfigurationName)
53                         : base (endpointConfigurationName)
54                 {
55                         callback_instance_type = callbackInstanceType;
56                 }
57
58                 public DuplexChannelFactory (Type callbackInstanceType,
59                         string endpointConfigurationName,
60                         EndpointAddress remoteAddress)
61                         : base (endpointConfigurationName, remoteAddress)
62                 {
63                         callback_instance_type = callbackInstanceType;
64                 }
65
66                 public DuplexChannelFactory (Type callbackInstanceType,
67                         ServiceEndpoint endpoint)
68                         : base (endpoint)
69                 {
70                         callback_instance_type = callbackInstanceType;
71                 }
72
73                 public DuplexChannelFactory (Type callbackInstanceType,
74                         Binding binding)
75                         : base (binding)
76                 {
77                         callback_instance_type = callbackInstanceType;
78                 }
79
80                 public DuplexChannelFactory (Type callbackInstanceType,
81                         Binding binding,
82                         string remoteAddress)
83                         : base (binding, new EndpointAddress (remoteAddress))
84                 {
85                         callback_instance_type = callbackInstanceType;
86                 }
87
88                 public DuplexChannelFactory (Type callbackInstanceType,
89                         Binding binding,
90                         EndpointAddress remoteAddress)
91                         : base (binding, remoteAddress)
92                 {
93                         callback_instance_type = callbackInstanceType;
94                 }
95
96                 public DuplexChannelFactory (object callbackObject)
97                         : this (new InstanceContext (callbackObject))
98                 {
99                 }
100
101                 public DuplexChannelFactory (object callbackObject,
102                         string endpointConfigurationName)
103                         : this (new InstanceContext (callbackObject), endpointConfigurationName)
104                 {
105                 }
106
107                 public DuplexChannelFactory (object callbackObject,
108                         string endpointConfigurationName,
109                         EndpointAddress remoteAddress)
110                         : this (new InstanceContext (callbackObject), endpointConfigurationName, remoteAddress)
111                 {
112                 }
113
114                 public DuplexChannelFactory (object callbackObject,
115                         ServiceEndpoint endpoint)
116                         : this (new InstanceContext (callbackObject), endpoint)
117                 {
118                 }
119
120                 public DuplexChannelFactory (object callbackObject,
121                         Binding binding)
122                         : this (new InstanceContext (callbackObject), binding)
123                 {
124                 }
125
126                 public DuplexChannelFactory (object callbackObject,
127                         Binding binding,
128                         string remoteAddress)
129                         : this (callbackObject, binding, new EndpointAddress (remoteAddress))
130                 {
131                 }
132
133                 public DuplexChannelFactory (object callbackObject,
134                         Binding binding,
135                         EndpointAddress remoteAddress)
136                         : this (new InstanceContext (callbackObject), binding, remoteAddress)
137                 {
138                 }
139
140                 public DuplexChannelFactory (InstanceContext callbackInstance)
141                         : base ()
142                 {
143                         callback_instance = callbackInstance;
144                 }
145
146                 public DuplexChannelFactory (InstanceContext callbackInstance,
147                         Binding binding)
148                         : base (binding)
149                 {
150                         callback_instance = callbackInstance;
151                 }
152
153                 public DuplexChannelFactory (InstanceContext callbackInstance,
154                         Binding binding,
155                         string remoteAddress)
156                         : this (callbackInstance, binding, new EndpointAddress (remoteAddress))
157                 {
158                 }
159
160                 public DuplexChannelFactory (InstanceContext callbackInstance,
161                         Binding binding,
162                         EndpointAddress remoteAddress)
163                         : base (binding, remoteAddress)
164                 {
165                         callback_instance = callbackInstance;
166                 }
167
168                 public DuplexChannelFactory (InstanceContext callbackInstance,
169                         string endpointConfigurationName,
170                         EndpointAddress remoteAddress)
171                         : base (endpointConfigurationName, remoteAddress)
172                 {
173                         callback_instance = callbackInstance;
174                 }
175
176                 public DuplexChannelFactory (InstanceContext callbackInstance,
177                         string endpointConfigurationName)
178                         : base (endpointConfigurationName)
179                 {
180                         callback_instance = callbackInstance;
181                 }
182
183                 public DuplexChannelFactory (InstanceContext callbackInstance,
184                         ServiceEndpoint endpoint)
185                         : base (endpoint)
186                 {
187                         callback_instance = callbackInstance;
188                 }
189
190                 // CreateChannel() instance methods
191
192                 public TChannel CreateChannel (InstanceContext callbackInstance)
193                 {
194                         return CreateChannel (callbackInstance, Endpoint.Address, null);
195                 }
196
197                 public override TChannel CreateChannel (EndpointAddress address, Uri via)
198                 {
199                         return CreateChannel (callback_instance, address, via);
200                 }
201
202                 public TChannel CreateChannel (InstanceContext callbackInstance, EndpointAddress address)
203                 {
204                         return CreateChannel (callbackInstance, address, null);
205                 }
206
207                 public virtual TChannel CreateChannel (InstanceContext callbackInstance, EndpointAddress address, Uri via)
208                 {
209                         if (callbackInstance == null)
210                                 throw new ArgumentNullException ("callbackInstance");
211
212                         EnsureOpened ();
213 #if DISABLE_REAL_PROXY
214                         Type type = ClientProxyGenerator.CreateProxyType (typeof (TChannel), Endpoint.Contract, true);
215                         // in .NET and SL2, it seems that the proxy is RealProxy.
216                         // But since there is no remoting in SL2 (and we have
217                         // no special magic), we have to use different approach
218                         // that should work either.
219                         object proxy = Activator.CreateInstance (type, new object [] {Endpoint, this, address, via});
220 #elif !MOBILE && !XAMMAC_4_5
221                         object proxy = new ClientRealProxy (typeof (TChannel), new DuplexClientRuntimeChannel (Endpoint, this, address, via), true).GetTransparentProxy ();
222 #else
223                         object proxy;
224                         throw new NotImplementedException ();
225 #endif
226
227                         ((IDuplexContextChannel) proxy).CallbackInstance = callbackInstance;
228
229                         return (TChannel) proxy;
230                 }
231
232                 // CreateChannel() factory methods
233
234                 static TChannel CreateChannelCore (DuplexChannelFactory<TChannel> cf, Func<DuplexChannelFactory<TChannel>,TChannel> f)
235                 {
236                         var ch = f (cf);
237                         ((CommunicationObject) (object) ch).Closed += delegate { cf.Close (); };
238                         return ch;
239                 }
240
241                 public static TChannel CreateChannel (object callbackObject, string endpointConfigurationName)
242                 {
243                         return CreateChannel (new InstanceContext (callbackObject), endpointConfigurationName);
244                 }
245
246                 public static TChannel CreateChannel (InstanceContext callbackInstance, string endpointConfigurationName)
247                 {
248                         return new DuplexChannelFactory<TChannel> (callbackInstance, endpointConfigurationName).CreateChannel (callbackInstance);
249                 }
250
251                 public static TChannel CreateChannel (object callbackObject, Binding binding, EndpointAddress endpointAddress)
252                 {
253                         return CreateChannel (new InstanceContext (callbackObject), binding, endpointAddress);
254                 }
255
256                 public static TChannel CreateChannel (InstanceContext callbackInstance, Binding binding, EndpointAddress endpointAddress)
257                 {
258                         return new DuplexChannelFactory<TChannel> (callbackInstance, binding, endpointAddress).CreateChannel (callbackInstance);
259                 }
260
261                 public static TChannel CreateChannel (object callbackObject, Binding binding, EndpointAddress endpointAddress, Uri via)
262                 {
263                         return CreateChannel (new InstanceContext (callbackObject), binding, endpointAddress, via);
264                 }
265
266                 public static TChannel CreateChannel (InstanceContext callbackInstance, Binding binding, EndpointAddress endpointAddress, Uri via)
267                 {
268                         return new DuplexChannelFactory<TChannel> (callbackInstance, binding).CreateChannel (callbackInstance, endpointAddress, via);
269                 }
270
271         }
272 }