2 // generic ChannelFactory_1.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System
.Collections
.ObjectModel
;
30 using System
.ServiceModel
.Channels
;
31 using System
.ServiceModel
.Description
;
32 using System
.ServiceModel
.Dispatcher
;
34 namespace System
.ServiceModel
36 // LAMESPEC: TChannel should have been defined as "where TChannel : IClientChannel".
37 // The returned channel is actually used as IClientChannel.
38 // (That's also likely why the type parameter name is TChannel, not TContract.)
39 public class ChannelFactory
<TChannel
>
40 : ChannelFactory
, IChannelFactory
<TChannel
>
42 public ChannelFactory ()
46 protected ChannelFactory (Type type
)
49 throw new ArgumentNullException ("type");
50 if (!type
.IsInterface
)
51 throw new InvalidOperationException ("The type argument to the generic ChannelFactory constructor must be an interface type.");
53 InitializeEndpoint (CreateDescription ());
56 public ChannelFactory (string endpointConfigurationName
)
58 if (endpointConfigurationName
== null)
59 throw new ArgumentNullException ("endpointConfigurationName");
61 InitializeEndpoint (endpointConfigurationName
, null);
64 public ChannelFactory (string endpointConfigurationName
,
65 EndpointAddress remoteAddress
)
67 if (endpointConfigurationName
== null)
68 throw new ArgumentNullException ("endpointConfigurationName");
70 InitializeEndpoint (endpointConfigurationName
, remoteAddress
);
73 public ChannelFactory (ServiceEndpoint endpoint
)
76 throw new ArgumentNullException ("serviceEndpoint");
78 InitializeEndpoint (endpoint
);
81 public ChannelFactory (Binding binding
, string remoteAddress
)
82 : this (binding
, new EndpointAddress (remoteAddress
))
86 public ChannelFactory (Binding binding
)
87 : this (binding
, (EndpointAddress
) null)
91 public ChannelFactory (Binding binding
, EndpointAddress remoteAddress
)
92 : this (typeof (TChannel
))
95 throw new ArgumentNullException ();
97 Endpoint
.Binding
= binding
;
98 Endpoint
.Address
= remoteAddress
;
101 internal object OwnerClientBase { get; set; }
103 public TChannel
CreateChannel ()
107 return CreateChannel (Endpoint
.Address
);
110 public TChannel
CreateChannel (EndpointAddress address
)
112 return CreateChannel (address
, null);
115 static TChannel
CreateChannelCore (ChannelFactory
<TChannel
> cf
, Func
<ChannelFactory
<TChannel
>, TChannel
> f
)
118 ((CommunicationObject
) (object) ch
).Closed
+= delegate { cf.Close (); }
;
122 public static TChannel
CreateChannel (Binding binding
, EndpointAddress address
)
124 return CreateChannelCore (new ChannelFactory
<TChannel
> (binding
, address
), f
=> f
.CreateChannel ());
127 public static TChannel
CreateChannel (Binding binding
, EndpointAddress address
, Uri via
)
129 return CreateChannelCore (new ChannelFactory
<TChannel
> (binding
), f
=> f
.CreateChannel (address
, via
));
132 public virtual TChannel
CreateChannel (EndpointAddress address
, Uri via
)
135 throw new InvalidOperationException ("MonoTouch does not support dynamic proxy code generation. Override this method or its caller to return specific client proxy instance");
137 var existing
= Endpoint
.Address
;
140 Endpoint
.Address
= address
;
142 Endpoint
.Validate ();
143 Type type
= ClientProxyGenerator
.CreateProxyType (typeof (TChannel
), Endpoint
.Contract
, false);
144 // in .NET and SL2, it seems that the proxy is RealProxy.
145 // But since there is no remoting in SL2 (and we have
146 // no special magic), we have to use different approach
147 // that should work either.
148 object proxy
= Activator
.CreateInstance (type
, new object [] {Endpoint, this, address ?? Endpoint.Address, via}
);
149 return (TChannel
) proxy
;
152 Endpoint
.Address
= existing
;
157 protected static TChannel
CreateChannel (string endpointConfigurationName
)
159 return CreateChannelCore (new ChannelFactory
<TChannel
> (endpointConfigurationName
), f
=> f
.CreateChannel ());
162 protected override ServiceEndpoint
CreateDescription ()
164 ContractDescription cd
= ContractDescription
.GetContract (typeof (TChannel
));
165 ServiceEndpoint ep
= new ServiceEndpoint (cd
);
166 ep
.Behaviors
.Add (new ClientCredentials ());
171 class DummyClientBase
<T
> : ClientBase
<T
> where T
: class
173 public DummyClientBase (ChannelFactory
<T
> factory
)