// instance members
ServiceEndpoint service_endpoint;
+ IChannelFactory factory;
protected ChannelFactory ()
{
}
- internal IChannelFactory OpenedChannelFactory { get; private set; }
+ internal IChannelFactory OpenedChannelFactory {
+ get {
+ if (factory == null) {
+ factory = CreateFactory ();
+ factory.Open ();
+ }
+
+ return factory;
+ }
+ private set {
+ factory = value;
+ }
+ }
public ServiceEndpoint Endpoint {
get { return service_endpoint; }
}
-#if !NET_2_1
public ClientCredentials Credentials {
get { return Endpoint.Behaviors.Find<ClientCredentials> (); }
}
-#endif
protected internal override TimeSpan DefaultCloseTimeout {
get { return Endpoint.Binding.CloseTimeout; }
#else
string contractName = Endpoint.Contract.ConfigurationName;
- ClientSection client = (ClientSection) ConfigurationManager.GetSection ("system.serviceModel/client");
+ ClientSection client = ConfigUtil.ClientSection;
ChannelEndpointElement res = null;
foreach (ChannelEndpointElement el in client.Endpoints) {
if (el.Contract == contractName && (endpointConfig == el.Name || endpointConfig == "*")) {
#if !NET_2_1
private void ApplyBehavior (string behaviorConfig)
{
- BehaviorsSection behaviorsSection = (BehaviorsSection) ConfigurationManager.GetSection ("system.serviceModel/behaviors");
+ BehaviorsSection behaviorsSection = ConfigUtil.BehaviorsSection;
EndpointBehaviorElement behaviorElement = behaviorsSection.EndpointBehaviors [behaviorConfig];
int i = 0;
foreach (BehaviorExtensionElement el in behaviorElement) {
protected virtual IChannelFactory CreateFactory ()
{
- bool session = false;
bool isOneWay = true; // check OperationDescription.IsOneWay
- bool isDuplex = Endpoint.Contract.CallbackContractType != null;
-
foreach (var od in Endpoint.Contract.Operations)
if (!od.IsOneWay) {
isOneWay = false;
BindingParameterCollection pl = CreateBindingParameters ();
- if (isDuplex) {
- switch (Endpoint.Contract.SessionMode) {
- case SessionMode.Required:
- if (Endpoint.Binding.CanBuildChannelFactory<IDuplexSessionChannel> (pl))
- return Endpoint.Binding.BuildChannelFactory<IDuplexSessionChannel> (pl);
- throw new InvalidOperationException ("The contract requires session channel, but the binding does not support it.");
- case SessionMode.Allowed:
- if (Endpoint.Binding.CanBuildChannelFactory<IDuplexChannel> (pl))
- return Endpoint.Binding.BuildChannelFactory<IDuplexChannel> (pl);
- goto case SessionMode.Required;
- default:
- if (Endpoint.Binding.CanBuildChannelFactory<IDuplexChannel> (pl))
- return Endpoint.Binding.BuildChannelFactory<IDuplexChannel> (pl);
- throw new InvalidOperationException ("The contract requires non-session channel, but the binding does not support it.");
- }
- } else if (isOneWay) {
+ // the assumption on the type of created channel could
+ // be wrong, but would mostly fit the actual
+ // requirements. No books have explained how it is done.
+
+ // try duplex
+ switch (Endpoint.Contract.SessionMode) {
+ case SessionMode.Required:
+ if (Endpoint.Binding.CanBuildChannelFactory<IDuplexSessionChannel> (pl))
+ return Endpoint.Binding.BuildChannelFactory<IDuplexSessionChannel> (pl);
+ break;
+ case SessionMode.Allowed:
+ if (Endpoint.Binding.CanBuildChannelFactory<IDuplexChannel> (pl))
+ return Endpoint.Binding.BuildChannelFactory<IDuplexChannel> (pl);
+ if (Endpoint.Binding.CanBuildChannelFactory<IDuplexSessionChannel> (pl))
+ return Endpoint.Binding.BuildChannelFactory<IDuplexSessionChannel> (pl);
+ break;
+ default:
+ if (Endpoint.Binding.CanBuildChannelFactory<IDuplexChannel> (pl))
+ return Endpoint.Binding.BuildChannelFactory<IDuplexChannel> (pl);
+ break;
+ }
+
+ if (Endpoint.Contract.CallbackContractType != null)
+ throw new InvalidOperationException ("The binding does not support duplex channel types that the contract requies for CallbackContractType.");
+
+ if (isOneWay) {
switch (Endpoint.Contract.SessionMode) {
case SessionMode.Required:
if (Endpoint.Binding.CanBuildChannelFactory<IOutputSessionChannel> (pl))
return Endpoint.Binding.BuildChannelFactory<IOutputSessionChannel> (pl);
- throw new InvalidOperationException ("The contract requires session channel, but the binding does not support it.");
+ break;
case SessionMode.Allowed:
if (Endpoint.Binding.CanBuildChannelFactory<IOutputChannel> (pl))
return Endpoint.Binding.BuildChannelFactory<IOutputChannel> (pl);
default:
if (Endpoint.Binding.CanBuildChannelFactory<IOutputChannel> (pl))
return Endpoint.Binding.BuildChannelFactory<IOutputChannel> (pl);
- throw new InvalidOperationException ("The contract requires non-session channel, but the binding does not support it.");
+ break;
}
- } else {
+ }
+ // both OneWay and non-OneWay contracts fall into here.
+ {
switch (Endpoint.Contract.SessionMode) {
case SessionMode.Required:
if (Endpoint.Binding.CanBuildChannelFactory<IRequestSessionChannel> (pl))
return Endpoint.Binding.BuildChannelFactory<IRequestSessionChannel> (pl);
- throw new InvalidOperationException ("The contract requires session channel, but the binding does not support it.");
+ break;
case SessionMode.Allowed:
if (Endpoint.Binding.CanBuildChannelFactory<IRequestChannel> (pl))
return Endpoint.Binding.BuildChannelFactory<IRequestChannel> (pl);
- goto case SessionMode.Required;
+ if (Endpoint.Binding.CanBuildChannelFactory<IRequestSessionChannel> (pl))
+ return Endpoint.Binding.BuildChannelFactory<IRequestSessionChannel> (pl);
+ break;
default:
if (Endpoint.Binding.CanBuildChannelFactory<IRequestChannel> (pl))
return Endpoint.Binding.BuildChannelFactory<IRequestChannel> (pl);
- throw new InvalidOperationException ("The contract requires non-session channel, but the binding does not support it.");
+ break;
}
}
+ throw new InvalidOperationException (String.Format ("The binding does not support any of the channel types that the contract '{0}' allows.", Endpoint.Contract.Name));
}
BindingParameterCollection CreateBindingParameters ()
Close ();
}
- [MonoTODO]
public T GetProperty<T> () where T : class
{
- throw new NotImplementedException ();
+ if (OpenedChannelFactory != null)
+ OpenedChannelFactory.GetProperty<T> ();
+ return null;
}
protected void EnsureOpened ()
{
+ if (Endpoint == null)
+ throw new InvalidOperationException ("A service endpoint must be configured for this channel factory");
+ if (Endpoint.Address == null)
+ throw new InvalidOperationException ("An EndpointAddress must be configured for this channel factory");
+ if (Endpoint.Contract == null)
+ throw new InvalidOperationException ("A service Contract must be configured for this channel factory");
+ if (Endpoint.Binding == null)
+ throw new InvalidOperationException ("A Binding must be configured for this channel factory");
+
if (State != CommunicationState.Opened)
Open ();
}
EndpointAddress remoteAddress)
{
InitializeEndpoint (CreateDescription ());
- service_endpoint.Address = remoteAddress;
+ if (remoteAddress != null)
+ service_endpoint.Address = remoteAddress;
ApplyConfiguration (endpointConfigurationName);
}
EndpointAddress remoteAddress)
{
InitializeEndpoint (CreateDescription ());
- service_endpoint.Binding = binding;
- service_endpoint.Address = remoteAddress;
+ if (binding != null)
+ service_endpoint.Binding = binding;
+ if (remoteAddress != null)
+ service_endpoint.Address = remoteAddress;
}
protected void InitializeEndpoint (ServiceEndpoint endpoint)
{
+ if (endpoint == null)
+ throw new ArgumentNullException ("endpoint");
service_endpoint = endpoint;
}
- [MonoTODO]
protected override void OnAbort ()
{
- throw new NotImplementedException ();
+ if (OpenedChannelFactory != null)
+ OpenedChannelFactory.Abort ();
}
- [MonoTODO]
+ Action<TimeSpan> close_delegate;
+ Action<TimeSpan> open_delegate;
+
+
protected override IAsyncResult OnBeginClose (
TimeSpan timeout, AsyncCallback callback, object state)
{
- throw new NotImplementedException ();
+ if (close_delegate == null)
+ close_delegate = new Action<TimeSpan> (OnClose);
+ return close_delegate.BeginInvoke (timeout, callback, state);
}
- [MonoTODO]
protected override IAsyncResult OnBeginOpen (
TimeSpan timeout, AsyncCallback callback, object state)
{
- throw new NotImplementedException ();
+ if (open_delegate == null)
+ open_delegate = new Action<TimeSpan> (OnClose);
+ return open_delegate.BeginInvoke (timeout, callback, state);
}
- [MonoTODO]
protected override void OnEndClose (IAsyncResult result)
{
- throw new NotImplementedException ();
+ if (close_delegate == null)
+ throw new InvalidOperationException ("Async close operation has not started");
+ close_delegate.EndInvoke (result);
}
- [MonoTODO]
protected override void OnEndOpen (IAsyncResult result)
{
- throw new NotImplementedException ();
+ if (open_delegate == null)
+ throw new InvalidOperationException ("Async close operation has not started");
+ open_delegate.EndInvoke (result);
}
- [MonoTODO]
protected override void OnClose (TimeSpan timeout)
{
+ if (OpenedChannelFactory != null)
+ OpenedChannelFactory.Close (timeout);
}
- [MonoTODO]
protected override void OnOpen (TimeSpan timeout)
{
}
protected override void OnOpening ()
{
+ base.OnOpening ();
OpenedChannelFactory = CreateFactory ();
- OpenedChannelFactory.Open ();
}
protected override void OnOpened ()
{
+ base.OnOpened ();
+ OpenedChannelFactory.Open ();
}
}