5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005-2006 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.Generic;
30 using System.ServiceModel.Channels;
31 using System.ServiceModel.Dispatcher;
33 namespace System.ServiceModel
35 public sealed class InstanceContext : CommunicationObject,
36 IExtensibleObject<InstanceContext>
39 object implementation;
40 int manual_flow_limit;
41 InstanceManager instance_manager;
42 bool is_user_instance_provider;
43 bool is_user_context_provider;
44 ExtensionCollection<InstanceContext> _extensions;
46 static InstanceContextIdleCallback idle_callback = new InstanceContextIdleCallback(NotifyIdle);
48 public InstanceContext (object implementation)
49 : this (null, implementation)
53 public InstanceContext (ServiceHostBase host)
58 public InstanceContext (ServiceHostBase host, object implementation)
59 : this (host, implementation, true)
63 internal InstanceContext (ServiceHostBase host, object implementation, bool userContextProvider)
66 this.implementation = implementation;
67 is_user_context_provider = userContextProvider;
70 internal bool IsUserProvidedInstance {
72 return is_user_instance_provider;
76 internal bool IsUserProvidedContext {
77 get { return is_user_context_provider; }
80 internal InstanceManager InstanceManager {
81 get { return instance_manager; }
82 set { instance_manager = value; }
85 protected internal override TimeSpan DefaultCloseTimeout {
86 get { return host.DefaultCloseTimeout; }
89 protected internal override TimeSpan DefaultOpenTimeout {
90 get { return host.DefaultOpenTimeout; }
93 public IExtensionCollection<InstanceContext> Extensions {
95 if (_extensions == null)
96 _extensions = new ExtensionCollection<InstanceContext> (this);
101 public ServiceHostBase Host {
105 public ICollection<IChannel> IncomingChannels {
106 get { throw new NotImplementedException (); }
109 public int ManualFlowControlLimit {
110 get { return manual_flow_limit; }
111 set { manual_flow_limit = value; }
114 public ICollection<IChannel> OutgoingChannels {
115 get { throw new NotImplementedException (); }
118 public object GetServiceInstance ()
120 return GetServiceInstance (null);
123 public object GetServiceInstance (Message message)
125 if (implementation == null && instance_manager != null) {
126 implementation = instance_manager.GetServiceInstance (this, message, ref is_user_instance_provider);
128 return implementation;
131 public int IncrementManualFlowControlLimit (int incrementBy)
133 throw new NotImplementedException ();
136 internal void CloseIfIdle () {
137 if (instance_manager.InstanceContextProvider != null && !IsUserProvidedContext) {
138 if (!instance_manager.InstanceContextProvider.IsIdle (this)) {
139 instance_manager.InstanceContextProvider.NotifyIdle (IdleCallback, this);
142 if (State != CommunicationState.Closed)
148 static void NotifyIdle (InstanceContext ctx) {
152 internal InstanceContextIdleCallback IdleCallback {
154 return idle_callback;
158 public void ReleaseServiceInstance ()
160 instance_manager.ReleaseServiceInstance (this, implementation);
161 // This does NOT dispose the instance implementation. See DispatrchRuntimeTest.TestInstanceBehavior2 (which never reports "Dispose").
162 implementation = null;
165 void DisposeInstance ()
167 var disp = implementation as IDisposable;
170 implementation = null;
173 protected override void OnAbort ()
178 protected override void OnFaulted ()
184 protected override void OnClosed ()
191 protected override void OnOpened ()
196 protected override void OnOpening ()
199 if (instance_manager != null)
200 instance_manager.Initialize (this);
203 Action<TimeSpan> open_delegate, close_delegate;
205 protected override IAsyncResult OnBeginOpen (
206 TimeSpan timeout, AsyncCallback callback, object state)
208 if (open_delegate == null)
209 open_delegate = new Action<TimeSpan> (OnOpen);
210 return open_delegate.BeginInvoke (timeout, callback, state);
213 protected override void OnEndOpen (IAsyncResult result)
215 open_delegate.EndInvoke (result);
218 protected override void OnOpen (TimeSpan timeout)
222 protected override IAsyncResult OnBeginClose (
223 TimeSpan timeout, AsyncCallback callback, object state)
225 if (close_delegate == null)
226 close_delegate = new Action<TimeSpan> (OnClose);
227 return close_delegate.BeginInvoke (timeout, callback, state);
230 protected override void OnEndClose (IAsyncResult result)
232 close_delegate.EndInvoke (result);
235 protected override void OnClose (TimeSpan timeout)