< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Dispatcher.InstanceBehavior
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Dispatcher/InstanceBehavior.cs
Line coverage
59%
Covered lines: 61
Uncovered lines: 41
Coverable lines: 102
Total lines: 281
Line coverage: 59.8%
Branch coverage
46%
Covered branches: 37
Total branches: 80
Branch coverage: 46.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)46.15%262668.18%
AfterReply(...)40%101036.84%
CanUnload(...)50%8844.44%
EnsureInstanceContextAsync()100%66100%
GetConstructor(...)0%440%
GetInstance(...)0%660%
GetInstance(...)16.66%6650%
Initialize(...)87.5%8887.5%
EnsureServiceInstance(...)50%2275%
ReleaseInstance(...)50%4444.44%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Dispatcher/InstanceBehavior.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Reflection;
 6using System.Threading.Tasks;
 7using CoreWCF.Channels;
 8using CoreWCF.Diagnostics;
 9using CoreWCF.Runtime;
 10
 11namespace CoreWCF.Dispatcher
 12{
 13    internal class InstanceBehavior
 14    {
 15        private const BindingFlags DefaultBindingFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.P
 16        private readonly IInstanceContextInitializer[] _initializers;
 17        private readonly IInstanceProvider _provider;
 18        private readonly InstanceContext _singleton;
 19        private readonly ImmutableDispatchRuntime _immutableRuntime;
 20        private readonly Type _serviceType;
 21
 66122        internal InstanceBehavior(DispatchRuntime dispatch, ImmutableDispatchRuntime immutableRuntime)
 23        {
 66124            _immutableRuntime = immutableRuntime;
 66125            _serviceType = dispatch.Type;
 66126            _initializers = EmptyArray<IInstanceContextInitializer>.ToArray(dispatch.InstanceContextInitializers);
 66127            _provider = dispatch.InstanceProvider;
 66128            _singleton = dispatch.SingletonInstanceContext;
 66129            InstanceContextProvider = dispatch.InstanceContextProvider;
 30
 66131            if (_provider == null)
 32            {
 12533                bool hasDefaultConstructor = dispatch.Type != null && InvokerUtil.HasDefaultConstructor(dispatch.Type);
 12534                if (_singleton == null)
 35                {
 036                    if (dispatch.Type != null && (dispatch.Type.GetTypeInfo().IsAbstract || dispatch.Type.GetTypeInfo().
 37                    {
 038                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.SFxSe
 39                    }
 40
 041                    if (!hasDefaultConstructor)
 42                    {
 043                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 044                            SR.Format(SR.SFxNoDefaultConstructor, dispatch.Type?.FullName ?? "Unknown")));
 45                    }
 46                }
 47
 12548                if (!hasDefaultConstructor)
 49                {
 2350                    if (_singleton == null || !_singleton.IsWellKnown)
 51                    {
 052                        CreateInstanceDelegate creator = InvokerUtil.GenerateCreateInstanceDelegate(dispatch.Type);
 053                        _provider = new InstanceProvider(creator);
 54                    }
 55                }
 56            }
 57
 66158            if (_singleton != null)
 59            {
 12560                _singleton.Behavior = this;
 61            }
 66162        }
 63
 978364        internal IInstanceContextProvider InstanceContextProvider { get; }
 65
 66        internal void AfterReply(ref MessageRpc rpc, ErrorBehavior error)
 67        {
 253868            InstanceContext context = rpc.InstanceContext;
 69
 253870            if (context != null)
 71            {
 72                try
 73                {
 253674                    if (rpc.Operation.ReleaseInstanceAfterCall)
 75                    {
 076                        if (context.State == CommunicationState.Opened)
 77                        {
 078                            context.ReleaseServiceInstance();
 79                        }
 80                    }
 253681                }
 082                catch (Exception e)
 83                {
 084                    if (Fx.IsFatal(e))
 85                    {
 086                        throw;
 87                    }
 088                    error.HandleError(e);
 089                }
 90
 91                try
 92                {
 253693                    context.UnbindRpc(rpc);
 253694                }
 095                catch (Exception e)
 96                {
 097                    if (Fx.IsFatal(e))
 98                    {
 099                        throw;
 100                    }
 0101                    error.HandleError(e);
 0102                }
 103            }
 2538104        }
 105
 106        internal bool CanUnload(InstanceContext instanceContext)
 107        {
 2332108            if (InstanceContextProviderBase.IsProviderSingleton(InstanceContextProvider))
 109            {
 0110                return false;
 111            }
 112
 2332113            if (InstanceContextProviderBase.IsProviderPerCall(InstanceContextProvider) ||
 2332114                InstanceContextProviderBase.IsProviderSessionful(InstanceContextProvider))
 115            {
 2332116                return true;
 117            }
 118
 119            //User provided InstanceContextProvider. Call the provider to check for idle.
 0120            if (!InstanceContextProvider.IsIdle(instanceContext))
 121            {
 0122                InstanceContextProvider.NotifyIdle(InstanceContext.NotifyIdleCallback, instanceContext);
 0123                return false;
 124            }
 0125            return true;
 126        }
 127
 128        internal async Task EnsureInstanceContextAsync(MessageRpc rpc)
 129        {
 2536130            if (rpc.InstanceContext == null)
 131            {
 2391132                rpc.InstanceContext = new InstanceContext(rpc.Host, false)
 2391133                {
 2391134                    ServiceThrottle = rpc.ChannelHandler.InstanceContextServiceThrottle
 2391135                };
 2391136                rpc.MessageRpcOwnsInstanceContextThrottle = false;
 137            }
 138
 2536139            rpc.OperationContext.SetInstanceContext(rpc.InstanceContext);
 2536140            rpc.InstanceContext.Behavior = this;
 141
 2536142            if (rpc.InstanceContext.State == CommunicationState.Created)
 143            {
 2391144                Task openTask = null;
 2391145                lock (rpc.InstanceContext.ThisLock)
 146                {
 2391147                    if (rpc.InstanceContext.State == CommunicationState.Created)
 148                    {
 2391149                        var helper = new TimeoutHelper(rpc.Channel.CloseTimeout);
 150                        // awaiting the task outside the lock is safe as OpenAsync will transition the state away from C
 151                        // it returns an uncompleted Task.
 2391152                        openTask = rpc.InstanceContext.OpenAsync(helper.GetCancellationToken());
 153                        Fx.Assert(rpc.InstanceContext.State != CommunicationState.Created, "InstanceContext.OpenAsync sh
 154                    }
 2391155                }
 156
 2391157                await openTask;
 158            }
 159
 2536160            rpc.InstanceContext.BindRpc(rpc);
 2536161        }
 162
 163        private static ConstructorInfo GetConstructor(Type type)
 164        {
 0165            foreach (ConstructorInfo constructor in type.GetConstructors(DefaultBindingFlags))
 166            {
 0167                if (constructor.GetParameters().Length == 0)
 168                {
 0169                    return constructor;
 170                }
 171            }
 0172            return null;
 173        }
 174
 175        internal object GetInstance(InstanceContext instanceContext)
 176        {
 0177            if (_provider == null)
 178            {
 0179                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0180                    SR.Format(SR.SFxNoDefaultConstructor, _serviceType?.FullName ?? "Unknown")));
 181            }
 182
 0183            return _provider.GetInstance(instanceContext);
 184        }
 185
 186        internal object GetInstance(InstanceContext instanceContext, Message request)
 187        {
 2391188            if (_provider == null)
 189            {
 0190                throw TraceUtility.ThrowHelperError(new InvalidOperationException(
 0191                    SR.Format(SR.SFxNoDefaultConstructor, _serviceType?.FullName ?? "Unknown")), request);
 192            }
 193
 2391194            return _provider.GetInstance(instanceContext, request);
 195        }
 196
 197        internal void Initialize(InstanceContext instanceContext)
 198        {
 2473199            OperationContext current = OperationContext.Current;
 2473200            Message message = current?.IncomingMessage;
 201
 2473202            if (current != null && current.InternalServiceChannel != null)
 203            {
 2391204                IContextChannel transparentProxy = (IContextChannel)current.InternalServiceChannel.Proxy;
 2391205                InstanceContextProvider.InitializeInstanceContext(instanceContext, message, transparentProxy);
 206            }
 207
 4946208            for (int i = 0; i < _initializers.Length; i++)
 209            {
 0210                _initializers[i].Initialize(instanceContext, message);
 211            }
 2473212        }
 213
 214        internal void EnsureServiceInstance(MessageRpc rpc)
 215        {
 2536216            if (rpc.Operation.ReleaseInstanceBeforeCall)
 217            {
 0218                rpc.InstanceContext.ReleaseServiceInstance();
 219            }
 220
 221            //if (TD.GetServiceInstanceStartIsEnabled())
 222            //{
 223            //    TD.GetServiceInstanceStart(rpc.EventTraceActivity);
 224            //}
 225
 2536226            rpc.Instance = rpc.InstanceContext.GetServiceInstance(rpc.Request);
 227
 228            //if (TD.GetServiceInstanceStopIsEnabled())
 229            //{
 230            //    TD.GetServiceInstanceStop(rpc.EventTraceActivity);
 231            //}
 2535232        }
 233
 234        internal void ReleaseInstance(InstanceContext instanceContext, object instance)
 235        {
 2389236            if (_provider != null)
 237            {
 238                try
 239                {
 2389240                    _provider.ReleaseInstance(instanceContext, instance);
 2389241                }
 0242                catch (Exception e)
 243                {
 0244                    if (Fx.IsFatal(e))
 245                    {
 0246                        throw;
 247                    }
 0248                    _immutableRuntime.ErrorBehavior.HandleError(e);
 0249                }
 250            }
 2389251        }
 252    }
 253
 254    internal class InstanceProvider : IInstanceProvider
 255    {
 256        private readonly CreateInstanceDelegate _creator;
 257
 258        internal InstanceProvider(CreateInstanceDelegate creator)
 259        {
 260            _creator = creator ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(creator));
 261        }
 262
 263        public object GetInstance(InstanceContext instanceContext)
 264        {
 265            return _creator();
 266        }
 267
 268        public object GetInstance(InstanceContext instanceContext, Message message)
 269        {
 270            return _creator();
 271        }
 272
 273        public void ReleaseInstance(InstanceContext instanceContext, object instance)
 274        {
 275            if (instance is IDisposable dispose)
 276            {
 277                dispose.Dispose();
 278            }
 279        }
 280    }
 281}