2 // DuplexChannelFactory.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
6 // Marcos Cobena (marcoscobena@gmail.com)
8 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
9 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
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;
38 namespace System.ServiceModel
40 public class DuplexChannelFactory<TChannel> : ChannelFactory<TChannel>
42 InstanceContext callback_instance;
43 Type callback_instance_type;
45 public DuplexChannelFactory (Type callbackInstanceType)
48 callback_instance_type = callbackInstanceType;
51 public DuplexChannelFactory (Type callbackInstanceType,
52 string endpointConfigurationName)
53 : base (endpointConfigurationName)
55 callback_instance_type = callbackInstanceType;
58 public DuplexChannelFactory (Type callbackInstanceType,
59 string endpointConfigurationName,
60 EndpointAddress remoteAddress)
61 : base (endpointConfigurationName, remoteAddress)
63 callback_instance_type = callbackInstanceType;
66 public DuplexChannelFactory (Type callbackInstanceType,
67 ServiceEndpoint endpoint)
70 callback_instance_type = callbackInstanceType;
73 public DuplexChannelFactory (Type callbackInstanceType,
77 callback_instance_type = callbackInstanceType;
80 public DuplexChannelFactory (Type callbackInstanceType,
83 : base (binding, new EndpointAddress (remoteAddress))
85 callback_instance_type = callbackInstanceType;
88 public DuplexChannelFactory (Type callbackInstanceType,
90 EndpointAddress remoteAddress)
91 : base (binding, remoteAddress)
93 callback_instance_type = callbackInstanceType;
96 public DuplexChannelFactory (object callbackObject)
97 : this (new InstanceContext (callbackObject))
101 public DuplexChannelFactory (object callbackObject,
102 string endpointConfigurationName)
103 : this (new InstanceContext (callbackObject), endpointConfigurationName)
107 public DuplexChannelFactory (object callbackObject,
108 string endpointConfigurationName,
109 EndpointAddress remoteAddress)
110 : this (new InstanceContext (callbackObject), endpointConfigurationName, remoteAddress)
114 public DuplexChannelFactory (object callbackObject,
115 ServiceEndpoint endpoint)
116 : this (new InstanceContext (callbackObject), endpoint)
120 public DuplexChannelFactory (object callbackObject,
122 : this (new InstanceContext (callbackObject), binding)
126 public DuplexChannelFactory (object callbackObject,
128 string remoteAddress)
129 : this (callbackObject, binding, new EndpointAddress (remoteAddress))
133 public DuplexChannelFactory (object callbackObject,
135 EndpointAddress remoteAddress)
136 : this (new InstanceContext (callbackObject), binding, remoteAddress)
140 public DuplexChannelFactory (InstanceContext callbackInstance)
143 callback_instance = callbackInstance;
146 public DuplexChannelFactory (InstanceContext callbackInstance,
150 callback_instance = callbackInstance;
153 public DuplexChannelFactory (InstanceContext callbackInstance,
155 string remoteAddress)
156 : this (callbackInstance, binding, new EndpointAddress (remoteAddress))
160 public DuplexChannelFactory (InstanceContext callbackInstance,
162 EndpointAddress remoteAddress)
163 : base (binding, remoteAddress)
165 callback_instance = callbackInstance;
168 public DuplexChannelFactory (InstanceContext callbackInstance,
169 string endpointConfigurationName,
170 EndpointAddress remoteAddress)
171 : base (endpointConfigurationName, remoteAddress)
173 callback_instance = callbackInstance;
176 public DuplexChannelFactory (InstanceContext callbackInstance,
177 string endpointConfigurationName)
178 : base (endpointConfigurationName)
180 callback_instance = callbackInstance;
183 public DuplexChannelFactory (InstanceContext callbackInstance,
184 ServiceEndpoint endpoint)
187 callback_instance = callbackInstance;
190 // CreateChannel() instance methods
192 public TChannel CreateChannel (InstanceContext callbackInstance)
194 return CreateChannel (callbackInstance, Endpoint.Address, null);
197 public override TChannel CreateChannel (EndpointAddress address, Uri via)
199 return CreateChannel (callback_instance, address, via);
202 public TChannel CreateChannel (InstanceContext callbackInstance, EndpointAddress address)
204 return CreateChannel (callbackInstance, address, null);
207 public virtual TChannel CreateChannel (InstanceContext callbackInstance, EndpointAddress address, Uri via)
209 if (callbackInstance == null)
210 throw new ArgumentNullException ("callbackInstance");
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 ();
224 throw new NotImplementedException ();
227 ((IDuplexContextChannel) proxy).CallbackInstance = callbackInstance;
229 return (TChannel) proxy;
232 // CreateChannel() factory methods
234 static TChannel CreateChannelCore (DuplexChannelFactory<TChannel> cf, Func<DuplexChannelFactory<TChannel>,TChannel> f)
237 ((CommunicationObject) (object) ch).Closed += delegate { cf.Close (); };
241 public static TChannel CreateChannel (object callbackObject, string endpointConfigurationName)
243 return CreateChannel (new InstanceContext (callbackObject), endpointConfigurationName);
246 public static TChannel CreateChannel (InstanceContext callbackInstance, string endpointConfigurationName)
248 return new DuplexChannelFactory<TChannel> (callbackInstance, endpointConfigurationName).CreateChannel (callbackInstance);
251 public static TChannel CreateChannel (object callbackObject, Binding binding, EndpointAddress endpointAddress)
253 return CreateChannel (new InstanceContext (callbackObject), binding, endpointAddress);
256 public static TChannel CreateChannel (InstanceContext callbackInstance, Binding binding, EndpointAddress endpointAddress)
258 return new DuplexChannelFactory<TChannel> (callbackInstance, binding, endpointAddress).CreateChannel (callbackInstance);
261 public static TChannel CreateChannel (object callbackObject, Binding binding, EndpointAddress endpointAddress, Uri via)
263 return CreateChannel (new InstanceContext (callbackObject), binding, endpointAddress, via);
266 public static TChannel CreateChannel (InstanceContext callbackInstance, Binding binding, EndpointAddress endpointAddress, Uri via)
268 return new DuplexChannelFactory<TChannel> (callbackInstance, binding).CreateChannel (callbackInstance, endpointAddress, via);