1 // 2 // InstanceContext.cs 3 // 4 // Author: 5 // Atsushi Enomoto <atsushi@ximian.com> 6 // 7 // Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com 8 // 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: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 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. 27 // 28 using System; 29 using System.Threading; 30 using System.Collections.Generic; 31 using System.ServiceModel.Channels; 32 using System.ServiceModel.Dispatcher; 33 34 namespace System.ServiceModel 35 { 36 public sealed class InstanceContext : CommunicationObject, 37 IExtensibleObject<InstanceContext> 38 { 39 ServiceHostBase host; 40 object implementation; 41 int manual_flow_limit; 42 InstanceManager instance_manager; 43 bool is_user_instance_provider; 44 bool is_user_context_provider; 45 ExtensionCollection<InstanceContext> _extensions; 46 47 static InstanceContextIdleCallback idle_callback = new InstanceContextIdleCallback(NotifyIdle); 48 InstanceContext(object implementation)49 public InstanceContext (object implementation) 50 : this (null, implementation) 51 { 52 } 53 InstanceContext(ServiceHostBase host)54 public InstanceContext (ServiceHostBase host) 55 : this (host, null) 56 { 57 } 58 InstanceContext(ServiceHostBase host, object implementation)59 public InstanceContext (ServiceHostBase host, object implementation) 60 : this (host, implementation, true) 61 { 62 } 63 InstanceContext(ServiceHostBase host, object implementation, bool userContextProvider)64 internal InstanceContext (ServiceHostBase host, object implementation, bool userContextProvider) 65 { 66 this.host = host; 67 this.implementation = implementation; 68 is_user_context_provider = userContextProvider; 69 } 70 71 internal bool IsUserProvidedInstance { 72 get { 73 return is_user_instance_provider; 74 } 75 } 76 77 internal bool IsUserProvidedContext { 78 get { return is_user_context_provider; } 79 } 80 81 internal InstanceManager InstanceManager { 82 get { return instance_manager; } 83 set { instance_manager = value; } 84 } 85 86 protected internal override TimeSpan DefaultCloseTimeout { 87 get { return host.DefaultCloseTimeout; } 88 } 89 90 protected internal override TimeSpan DefaultOpenTimeout { 91 get { return host.DefaultOpenTimeout; } 92 } 93 94 public IExtensionCollection<InstanceContext> Extensions { 95 get { 96 if (_extensions == null) 97 _extensions = new ExtensionCollection<InstanceContext> (this); 98 return _extensions; 99 } 100 } 101 102 public ServiceHostBase Host { 103 get { return host; } 104 } 105 106 public ICollection<IChannel> IncomingChannels { 107 get { throw new NotImplementedException (); } 108 } 109 110 public int ManualFlowControlLimit { 111 get { return manual_flow_limit; } 112 set { manual_flow_limit = value; } 113 } 114 115 public ICollection<IChannel> OutgoingChannels { 116 get { throw new NotImplementedException (); } 117 } 118 GetServiceInstance()119 public object GetServiceInstance () 120 { 121 return GetServiceInstance (null); 122 } 123 GetServiceInstance(Message message)124 public object GetServiceInstance (Message message) 125 { 126 if (implementation == null && instance_manager != null) { 127 implementation = instance_manager.GetServiceInstance (this, message, ref is_user_instance_provider); 128 } 129 return implementation; 130 } 131 IncrementManualFlowControlLimit(int incrementBy)132 public int IncrementManualFlowControlLimit (int incrementBy) 133 { 134 throw new NotImplementedException (); 135 } 136 CloseIfIdle()137 internal void CloseIfIdle () { 138 if (instance_manager.InstanceContextProvider != null && !IsUserProvidedContext) { 139 if (!instance_manager.InstanceContextProvider.IsIdle (this)) { 140 instance_manager.InstanceContextProvider.NotifyIdle (IdleCallback, this); 141 } 142 else { 143 if (State != CommunicationState.Closed) 144 Close (); 145 } 146 } 147 } 148 NotifyIdle(InstanceContext ctx)149 static void NotifyIdle (InstanceContext ctx) { 150 ctx.CloseIfIdle (); 151 } 152 153 internal InstanceContextIdleCallback IdleCallback { 154 get { 155 return idle_callback; 156 } 157 } 158 ReleaseServiceInstance()159 public void ReleaseServiceInstance () 160 { 161 instance_manager.ReleaseServiceInstance (this, implementation); 162 // This does NOT dispose the instance implementation. See DispatrchRuntimeTest.TestInstanceBehavior2 (which never reports "Dispose"). 163 implementation = null; 164 } 165 DisposeInstance()166 void DisposeInstance () 167 { 168 var disp = implementation as IDisposable; 169 if (disp != null) 170 disp.Dispose (); 171 implementation = null; 172 } 173 OnAbort()174 protected override void OnAbort () 175 { 176 DisposeInstance (); 177 } 178 OnFaulted()179 protected override void OnFaulted () 180 { 181 DisposeInstance (); 182 base.OnFaulted (); 183 } 184 OnClosed()185 protected override void OnClosed () 186 { 187 DisposeInstance (); 188 base.OnClosed (); 189 } 190 191 [MonoTODO] OnOpened()192 protected override void OnOpened () 193 { 194 base.OnOpened (); 195 } 196 OnOpening()197 protected override void OnOpening () 198 { 199 base.OnOpening (); 200 if (instance_manager != null) 201 instance_manager.Initialize (this); 202 } 203 204 Action<TimeSpan> open_delegate, close_delegate; 205 OnBeginOpen( TimeSpan timeout, AsyncCallback callback, object state)206 protected override IAsyncResult OnBeginOpen ( 207 TimeSpan timeout, AsyncCallback callback, object state) 208 { 209 if (open_delegate == null) 210 open_delegate = new Action<TimeSpan> (OnOpen); 211 return open_delegate.BeginInvoke (timeout, callback, state); 212 } 213 OnEndOpen(IAsyncResult result)214 protected override void OnEndOpen (IAsyncResult result) 215 { 216 open_delegate.EndInvoke (result); 217 } 218 OnOpen(TimeSpan timeout)219 protected override void OnOpen (TimeSpan timeout) 220 { 221 } 222 OnBeginClose( TimeSpan timeout, AsyncCallback callback, object state)223 protected override IAsyncResult OnBeginClose ( 224 TimeSpan timeout, AsyncCallback callback, object state) 225 { 226 if (close_delegate == null) 227 close_delegate = new Action<TimeSpan> (OnClose); 228 return close_delegate.BeginInvoke (timeout, callback, state); 229 } 230 OnEndClose(IAsyncResult result)231 protected override void OnEndClose (IAsyncResult result) 232 { 233 close_delegate.EndInvoke (result); 234 } 235 OnClose(TimeSpan timeout)236 protected override void OnClose (TimeSpan timeout) 237 { 238 } 239 240 [MonoTODO] 241 public SynchronizationContext SynchronizationContext { 242 get { throw new NotImplementedException (); } 243 set { throw new NotImplementedException (); } 244 } 245 } 246 } 247