2 // ChannelFactoryBase.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.
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
32 using System.ServiceModel;
33 using System.ServiceModel.Dispatcher;
35 namespace System.ServiceModel.Channels
37 internal interface IHasMessageEncoder
39 MessageEncoder MessageEncoder { get; }
42 internal abstract class TransportChannelFactoryBase<TChannel> : ChannelFactoryBase<TChannel>, IHasMessageEncoder
44 protected TransportChannelFactoryBase (TransportBindingElement source, BindingContext ctx)
49 public TransportBindingElement Transport { get; private set; }
51 public MessageEncoder MessageEncoder { get; internal set; }
53 Action<TimeSpan> open_delegate;
55 protected override IAsyncResult OnBeginOpen (TimeSpan timeout,
56 AsyncCallback callback, object state)
58 if (open_delegate == null)
59 open_delegate = new Action<TimeSpan> (OnOpen);
60 return open_delegate.BeginInvoke (timeout, callback, state);
63 protected override void OnEndOpen (IAsyncResult result)
65 if (open_delegate == null)
66 throw new InvalidOperationException ("Async open operation has not started");
67 open_delegate.EndInvoke (result);
70 protected override void OnOpen (TimeSpan timeout)
74 /* commented out as it is in doubt.
75 public override T GetProperty<T> ()
77 if (typeof (T) == typeof (MessageVersion))
78 return (T) (object) MessageEncoder.MessageVersion;
79 return base.GetProperty<T> ();
84 public abstract class ChannelFactoryBase<TChannel>
85 : ChannelFactoryBase, IChannelFactory<TChannel>
87 List<TChannel> channels = new List<TChannel> ();
89 protected ChannelFactoryBase ()
90 : this (DefaultCommunicationTimeouts.Instance)
94 protected ChannelFactoryBase (
95 IDefaultCommunicationTimeouts timeouts)
100 public TChannel CreateChannel (
101 EndpointAddress remoteAddress)
103 if (remoteAddress == null)
104 throw new ArgumentNullException ("remoteAddress");
105 return CreateChannel (remoteAddress, remoteAddress.Uri);
108 public TChannel CreateChannel (
109 EndpointAddress remoteAddress, Uri via)
111 if (remoteAddress == null)
112 throw new ArgumentNullException ("remoteAddress");
114 throw new ArgumentNullException ("via");
116 ValidateCreateChannel ();
117 var ch = OnCreateChannel (remoteAddress, via);
122 protected abstract TChannel OnCreateChannel (
123 EndpointAddress remoteAddress, Uri via);
125 protected override void OnAbort ()
127 // this implicitly premises: TChannel is IChannel
128 foreach (IChannel ch in channels)
133 protected override void OnClose (TimeSpan timeout)
135 DateTime start = DateTime.Now;
136 // this implicitly premises: TChannel is IChannel
137 foreach (IChannel ch in channels)
138 ch.Close (timeout - (DateTime.Now - start));
139 base.OnClose (timeout - (DateTime.Now - start));
142 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
144 // base impl. will call this.OnClose()
145 // FIXME: use async BeginClose/EndClose on the channels.
146 return base.OnBeginClose (timeout, callback, state);
149 protected override void OnEndClose (IAsyncResult result)
151 // base impl. will call this.OnClose()
152 base.OnEndClose (result);
155 protected void ValidateCreateChannel ()
157 ThrowIfDisposedOrNotOpen ();
158 if (State == CommunicationState.Faulted)
159 throw new CommunicationObjectFaultedException ();
163 public abstract class ChannelFactoryBase
164 : ChannelManagerBase, IChannelFactory, ICommunicationObject
166 TimeSpan open_timeout, close_timeout, receive_timeout, send_timeout;
168 protected ChannelFactoryBase ()
169 : this (DefaultCommunicationTimeouts.Instance)
173 protected ChannelFactoryBase (
174 IDefaultCommunicationTimeouts timeouts)
176 open_timeout = timeouts.OpenTimeout;
177 close_timeout = timeouts.CloseTimeout;
178 send_timeout = timeouts.SendTimeout;
179 receive_timeout = timeouts.ReceiveTimeout;
182 protected internal override TimeSpan DefaultCloseTimeout {
183 get { return close_timeout; }
186 protected internal override TimeSpan DefaultOpenTimeout {
187 get { return open_timeout; }
190 protected internal override TimeSpan DefaultReceiveTimeout {
191 get { return receive_timeout; }
194 protected internal override TimeSpan DefaultSendTimeout {
195 get { return send_timeout; }
198 public virtual T GetProperty<T> () where T : class
203 protected override void OnAbort ()
205 // what should we do here?
208 Action<TimeSpan> close_delegate;
210 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
212 if (close_delegate == null)
213 close_delegate = new Action<TimeSpan> (OnClose);
214 return close_delegate.BeginInvoke (timeout, callback, state);
217 protected override void OnEndClose (IAsyncResult result)
219 if (close_delegate == null)
220 throw new InvalidOperationException ("Async close operation has not started");
221 close_delegate.EndInvoke (result);
224 protected override void OnClose (TimeSpan timeout)
226 // what should we do here?