| File: System\ServiceModel\InstanceContext.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Runtime; using System.ServiceModel.Channels; using System.ServiceModel.Diagnostics; using System.ServiceModel.Dispatcher; using System.Threading; using System.Threading.Tasks; namespace System.ServiceModel { public sealed class InstanceContext : CommunicationObject, IExtensibleObject<InstanceContext> { private InstanceBehavior _behavior; private ConcurrencyInstanceContextFacet _concurrency; private ServiceChannelManager _channels; private ExtensionCollection<InstanceContext> _extensions; private object _serviceInstanceLock = new object(); private SynchronizationContext _synchronizationContext; private object _userObject; private bool _wellKnown; private bool _isUserCreated; public InstanceContext(object implementation) : this(implementation, true) { } internal InstanceContext(object implementation, bool isUserCreated) : this(implementation, true, isUserCreated) { } internal InstanceContext(object implementation, bool wellKnown, bool isUserCreated) { if (implementation != null) { _userObject = implementation; _wellKnown = wellKnown; } _channels = new ServiceChannelManager(this); _isUserCreated = isUserCreated; } internal InstanceBehavior Behavior { get { return _behavior; } set { if (_behavior == null) { _behavior = value; } } } internal ConcurrencyInstanceContextFacet Concurrency { get { if (_concurrency == null) { lock (ThisLock) { if (_concurrency == null) { _concurrency = new ConcurrencyInstanceContextFacet(); } } } return _concurrency; } } protected override TimeSpan DefaultCloseTimeout { get { return ServiceDefaults.CloseTimeout; } } protected override TimeSpan DefaultOpenTimeout { get { return ServiceDefaults.OpenTimeout; } } public IExtensionCollection<InstanceContext> Extensions { get { ThrowIfClosed(); lock (ThisLock) { if (_extensions == null) { _extensions = new ExtensionCollection<InstanceContext>(this, ThisLock); } return _extensions; } } } public ICollection<IChannel> IncomingChannels { get { ThrowIfClosed(); return _channels.IncomingChannels; } } public ICollection<IChannel> OutgoingChannels { get { ThrowIfClosed(); return _channels.OutgoingChannels; } } public SynchronizationContext SynchronizationContext { get { return _synchronizationContext; } set { ThrowIfClosedOrOpened(); _synchronizationContext = value; } } new internal object ThisLock { get { return base.ThisLock; } } internal object UserObject { get { return _userObject; } } protected override void OnAbort() { _channels.Abort(); } internal void BindRpc(ref MessageRpc rpc) { ThrowIfClosed(); _channels.IncrementActivityCount(); rpc.SuccessfullyBoundInstance = true; } internal void FaultInternal() { Fault(); } public object GetServiceInstance(Message message) { lock (_serviceInstanceLock) { ThrowIfClosedOrNotOpen(); object current = _userObject; if (current != null) { return current; } if (_behavior == null) { Exception error = new InvalidOperationException(SRP.SFxInstanceNotInitialized); if (message != null) { throw TraceUtility.ThrowHelperError(error, message); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error); } } object newUserObject; if (message != null) { newUserObject = _behavior.GetInstance(this, message); } else { newUserObject = _behavior.GetInstance(this); } if (newUserObject != null) { SetUserObject(newUserObject); } return newUserObject; } } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return OnCloseAsync(timeout).ToApm(callback, state); } protected override void OnEndClose(IAsyncResult result) { result.ToApmEnd(); } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return new CompletedAsyncResult(callback, state); } protected override void OnEndOpen(IAsyncResult result) { CompletedAsyncResult.End(result); } protected override void OnClose(TimeSpan timeout) { _channels.Close(timeout); } protected override void OnClosed() => base.OnClosed(); protected override void OnFaulted() => base.OnFaulted(); protected override void OnOpen(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); } protected override void OnOpened() { base.OnOpened(); } protected override void OnOpening() { base.OnOpening(); } protected internal override Task OnCloseAsync(TimeSpan timeout) { return _channels.CloseAsync(timeout); } protected internal override Task OnOpenAsync(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); return TaskHelpers.CompletedTask(); } private void SetUserObject(object newUserObject) { if (_behavior != null && !_wellKnown) { object oldUserObject = Interlocked.Exchange(ref _userObject, newUserObject); } } internal void UnbindRpc(ref MessageRpc rpc) { if (rpc.InstanceContext == this && rpc.SuccessfullyBoundInstance) { _channels.DecrementActivityCount(); } } } }