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 ()
47 protected ChannelFactory (Type type)
50 throw new ArgumentNullException ("type");
51 if (!type.IsInterface)
52 throw new InvalidOperationException ("The type argument to the generic ChannelFactory constructor must be an interface type.");
54 InitializeEndpoint (CreateDescription ());
57 public ChannelFactory (string endpointConfigurationName)
59 if (endpointConfigurationName == null)
60 throw new ArgumentNullException ("endpointConfigurationName");
62 InitializeEndpoint (endpointConfigurationName, null);
65 public ChannelFactory (string endpointConfigurationName,
66 EndpointAddress remoteAddress)
68 if (endpointConfigurationName == null)
69 throw new ArgumentNullException ("endpointConfigurationName");
71 InitializeEndpoint (endpointConfigurationName, remoteAddress);
74 public ChannelFactory (ServiceEndpoint endpoint)
77 throw new ArgumentNullException ("serviceEndpoint");
79 InitializeEndpoint (endpoint);
82 public ChannelFactory (Binding binding, string remoteAddress)
83 : this (binding, new EndpointAddress (remoteAddress))
87 public ChannelFactory (Binding binding)
88 : this (binding, (EndpointAddress) null)
92 public ChannelFactory (Binding binding, EndpointAddress remoteAddress)
93 : this (typeof (TChannel))
96 throw new ArgumentNullException ();
98 Endpoint.Binding = binding;
99 Endpoint.Address = remoteAddress;
102 internal object OwnerClientBase { get; set; }
104 public TChannel CreateChannel ()
106 return CreateChannel (Endpoint.Address);
109 public TChannel CreateChannel (EndpointAddress address)
111 return CreateChannel (address, null);
114 public static TChannel CreateChannel (Binding binding, EndpointAddress address)
116 return new ChannelFactory<TChannel> (binding, address).CreateChannel ();
119 public static TChannel CreateChannel (Binding binding, EndpointAddress address, Uri via)
121 return new ChannelFactory<TChannel> (binding).CreateChannel (address, via);
124 public virtual TChannel CreateChannel (EndpointAddress address, Uri via)
127 Type type = ClientProxyGenerator.CreateProxyType (typeof (TChannel), Endpoint.Contract);
128 // in .NET and SL2, it seems that the proxy is RealProxy.
129 // But since there is no remoting in SL2 (and we have
130 // no special magic), we have to use different approach
131 // that should work either.
132 object proxy = Activator.CreateInstance (type, new object [] {Endpoint, this});
133 return (TChannel) proxy;
136 protected static TChannel CreateChannel (string endpointConfigurationName)
138 return new ChannelFactory<TChannel> (endpointConfigurationName).CreateChannel ();
141 protected override ServiceEndpoint CreateDescription ()
143 ContractDescription cd = ContractDescription.GetContract (typeof (TChannel));
144 ServiceEndpoint ep = new ServiceEndpoint (cd);
146 ep.Behaviors.Add (new ClientCredentials ());
152 class DummyClientBase<T> : ClientBase<T> where T : class
154 public DummyClientBase (ChannelFactory<T> factory)