Dispose() public méthode

public Dispose ( ) : void
Résultat void
Exemple #1
0
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState GetResponse_OnMethodBegin <TTarget>(TTarget instance)
        {
            if (instance is HttpWebRequest request && IsTracingEnabled(request))
            {
                Tracer tracer = Tracer.Instance;

                // Check if any headers were injected by a previous call to GetRequestStream
                var spanContext = tracer.Propagator.Extract(request.Headers.Wrap());

                Scope scope = null;

                try
                {
                    scope = ScopeFactory.CreateOutboundHttpScope(tracer, request.Method, request.RequestUri, IntegrationId, out var tags, spanContext?.SpanId);

                    if (scope != null)
                    {
                        // add distributed tracing headers to the HTTP request
                        tracer.Propagator.Inject(scope.Span.Context, request.Headers.Wrap());

                        return(new CallTargetState(scope));
                    }
                }
                catch
                {
                    scope?.Dispose();
                    throw;
                }
            }

            return(CallTargetState.GetDefault());
        }
Exemple #2
0
 internal static CallTargetReturn EndInvocationVoid(Exception exception, Scope scope, ILambdaExtensionRequest requestBuilder)
 {
     scope?.Dispose();
     Flush();
     NotifyExtensionEnd(requestBuilder, scope, exception != null);
     return(CallTargetReturn.GetDefault());
 }
        private void OnBeginRequest(object sender, EventArgs eventArgs)
        {
            Scope scope = null;

            try
            {
                var tracer = Tracer.Instance;

                if (!tracer.Settings.IsIntegrationEnabled(IntegrationName))
                {
                    // integration disabled
                    return;
                }

                var httpContext = (sender as HttpApplication)?.Context;

                if (httpContext == null)
                {
                    return;
                }

                HttpRequest httpRequest       = httpContext.Request;
                SpanContext propagatedContext = null;

                if (tracer.ActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers = httpRequest.Headers.Wrap();
                        propagatedContext = SpanContextPropagator.Instance.Extract(headers);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Error extracting propagated HTTP headers.");
                    }
                }

                string host         = httpRequest.Headers.Get("Host");
                string httpMethod   = httpRequest.HttpMethod.ToUpperInvariant();
                string url          = httpRequest.RawUrl.ToLowerInvariant();
                string path         = UriHelpers.GetRelativeUrl(httpRequest.Url, tryRemoveIds: true);
                string resourceName = $"{httpMethod} {path.ToLowerInvariant()}";

                scope = tracer.StartActive(_requestOperationName, propagatedContext);
                scope.Span.DecorateWebServerSpan(resourceName, httpMethod, host, url);

                // set analytics sample rate if enabled
                var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true);
                scope.Span.SetMetric(Tags.Analytics, analyticsSampleRate);

                httpContext.Items[_httpContextScopeKey] = scope;
            }
            catch (Exception ex)
            {
                // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case...
                scope?.Dispose();
                Log.Error(ex, "Datadog ASP.NET HttpModule instrumentation error");
            }
        }
Exemple #4
0
        /// <summary>
        /// Dispose the scope and container
        /// </summary>
        public void Dispose()
        {
            // When startup was called, but shutdown not, do this now
            if (_isStartedUp && !_isShutDown)
            {
                // Auto shutdown
                using (new NoSynchronizationContextScope())
                {
                    try
                    {
                        ShutdownAsync().Wait();
                    }
                    catch (AggregateException ex)
                    {
                        throw ex.GetBaseException();
                    }
                }
            }

            if (_disposables.Count > 0)
            {
                var reversedDisposables = _disposables.Reverse().Where(disposable => disposable != null).ToList();
                _disposables.Clear();
                foreach (var disposable in reversedDisposables)
                {
                    disposable?.Dispose();
                }
            }

            Scope?.Dispose();
            Container?.Dispose();
            Resolver.Dispose();
        }
Exemple #5
0
 internal static TReturn EndInvocationAsync <TReturn>(TReturn returnValue, Exception exception, Scope scope, ILambdaExtensionRequest requestBuilder)
 {
     scope?.Dispose();
     Flush();
     NotifyExtensionEnd(requestBuilder, exception != null);
     return(returnValue);
 }
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         Scope?.Dispose();
     }
 }
        public static bool EndInvokeAction(object asyncControllerActionInvoker, object asyncResult, int opCode, int mdToken)
        {
            Scope scope       = null;
            var   httpContext = HttpContext.Current;

            try
            {
                scope = httpContext?.Items[HttpContextKey] as Scope;
            }
            catch (Exception ex)
            {
                Log.ErrorException("Error instrumenting method {0}", ex, $"{AsyncActionInvokerTypeName}.EndInvokeAction()");
            }

            var endInvokeAction = Emit.DynamicMethodBuilder <Func <object, object, bool> >
                                  .GetOrCreateMethodCallDelegate(
                AsyncActionInvokerType,
                "EndInvokeAction",
                (OpCodeValue)opCode);

            try
            {
                // call the original method, inspecting (but not catching) any unhandled exceptions
                return(endInvokeAction(asyncControllerActionInvoker, asyncResult));
            }
            catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false)
            {
                // unreachable code
                throw;
            }
            finally
            {
                scope?.Dispose();
            }
        }
Exemple #8
0
        public static bool EndInvokeAction(dynamic asyncControllerActionInvoker, dynamic asyncResult)
        {
            Scope scope       = null;
            var   httpContext = HttpContext.Current;

            try
            {
                scope = httpContext?.Items[HttpContextKey] as Scope;
            }
            catch (Exception ex)
            {
                Log.ErrorException("Error instrumenting method {0}", ex, "System.Web.Mvc.Async.IAsyncActionInvoker.EndInvokeAction()");
            }

            try
            {
                // call the original method, inspecting (but not catching) any unhandled exceptions
                return((bool)asyncControllerActionInvoker.EndInvokeAction(asyncResult));
            }
            catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false)
            {
                // unreachable code
                throw;
            }
            finally
            {
                scope?.Dispose();
            }
        }
Exemple #9
0
        public void Dispose()
        {
            HealthManager.OnDead      -= MobRebirth_OnDead;
            HealthManager.OnGotDamage -= OnDecreaseHP;
            AIManager.OnStateChanged  -= AIManager_OnStateChanged;

            Scope?.Dispose();
        }
Exemple #10
0
 /// <inheritdoc/>
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         MemoryBuffer?.Dispose();
         Scope?.Dispose();
     }
     base.Dispose(disposing);
 }
Exemple #11
0
        internal static TReturn EndInvocationAsync <TReturn>(TReturn returnValue, Exception exception, Scope scope, ILambdaExtensionRequest requestBuilder)
        {
            var json = SerializeObject(returnValue);

            Flush();
            NotifyExtensionEnd(requestBuilder, scope, exception != null, json);
            scope?.Dispose();
            return(returnValue);
        }
Exemple #12
0
 protected virtual void Dispose(bool disposing)
 {
     if (View != null)
     {
         View.Closed -= View_Closed;
         View.Close();
     }
     viewLocator.Views.Remove(this);
     Scope?.Dispose();
 }
Exemple #13
0
 /// <summary>
 /// 析构
 /// </summary>
 public void Dispose()
 {
     if (IsDisposed)
     {
         return;
     }
     IsDisposed = true;
     Command?.Dispose();
     Scope?.Dispose();
 }
Exemple #14
0
        public static bool EndInvokeAction(
            object asyncControllerActionInvoker,
            object asyncResult,
            int opCode,
            int mdToken,
            long moduleVersionPtr)
        {
            Scope scope       = null;
            var   httpContext = HttpContext.Current;

            try
            {
                scope = httpContext?.Items[HttpContextKey] as Scope;
            }
            catch (Exception ex)
            {
                Log.ErrorException("Error instrumenting method {0}", ex, $"{AsyncActionInvokerTypeName}.EndInvokeAction()");
            }

            Func <object, object, bool> instrumentedMethod;

            try
            {
                var asyncActionInvokerType = asyncControllerActionInvoker.GetInstrumentedInterface(AsyncActionInvokerTypeName);

                instrumentedMethod = MethodBuilder <Func <object, object, bool> >
                                     .Start(moduleVersionPtr, mdToken, opCode, nameof(EndInvokeAction))
                                     .WithConcreteType(asyncActionInvokerType)
                                     .WithParameters(asyncResult)
                                     .WithNamespaceAndNameFilters(ClrNames.Bool, ClrNames.IAsyncResult)
                                     .Build();
            }
            catch (Exception ex)
            {
                Log.ErrorException($"Error resolving {AsyncActionInvokerTypeName}.{nameof(EndInvokeAction)}(...)", ex);
                throw;
            }

            try
            {
                // call the original method, inspecting (but not catching) any unhandled exceptions
                return(instrumentedMethod(asyncControllerActionInvoker, asyncResult));
            }
            catch (Exception ex)
            {
                scope?.Span.SetException(ex);
                throw;
            }
            finally
            {
                scope?.Dispose();
            }
        }
        public override void DisposeScope()
        {
            // IMPORTANT: HACK to create fake http context for job to allow the LightInject PerWebRequestScopeManager to work correctly when running in background jobs
            // Umbraco is hardcoded to using MixedLightInjectScopeManagerProvider so its really really hard to get around so this hack is the easiest way to handle this.
            if (HttpContext.Current == null)
            {
                HttpContext.Current = new HttpContext(new HttpRequest("PerWebRequestScopeManager", "https://localhost/PerWebRequestScopeManager", string.Empty),
                                                      new HttpResponse(new StringWriter()));
            }

            _scope?.Dispose();
        }
Exemple #16
0
        private void OnBeginRequest(object sender, EventArgs eventArgs)
        {
            var tracer = Tracer.Instance;

            if (!tracer.Settings.IsIntegrationEnabled(IntegrationName))
            {
                // integration disabled
                return;
            }

            Scope scope = null;

            try
            {
                if (!TryGetContext(sender, out var httpContext))
                {
                    return;
                }

                SpanContext propagatedContext = null;

                if (tracer.ActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers = httpContext.Request.Headers.Wrap();
                        propagatedContext = SpanContextPropagator.Instance.Extract(headers);
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorException("Error extracting propagated HTTP headers.", ex);
                    }
                }

                scope = tracer.StartActive(_operationName, propagatedContext);

                // set analytics sample rate if enabled
                var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true);
                scope.Span.SetMetric(Tags.Analytics, analyticsSampleRate);

                httpContext.Items[_httpContextDelegateKey] = HttpContextSpanIntegrationDelegate.CreateAndBegin(httpContext, scope);
            }
            catch (Exception ex)
            {
                // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case...
                scope?.Dispose();

                Log.ErrorException("Datadog ASP.NET HttpModule instrumentation error", ex);
            }
        }
 /// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 public void Dispose()
 {
     try
     {
         if (_httpContext != null)
         {
             _scope?.Span?.SetTag("http.status_code", _httpContext.Response.StatusCode.ToString());
         }
     }
     finally
     {
         _scope?.Dispose();
     }
 }
Exemple #18
0
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    HttpContext.Request.RequestStream.Close();
                    HttpContext.Response.ResponseStream.Close();
                    Scope?.Dispose();
                    Thread.CurrentPrincipal = null;
                }

                disposedValue = true;
            }
        }
Exemple #19
0
        protected virtual void Dispose(bool disposing)
        {
            if (isDisposed)
            {
                return;
            }

            if (disposing)
            {
                View.Closed -= View_Closed;
                Scope?.Dispose();
                Disposed?.Invoke();
            }

            isDisposed = true;
        }
 /// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 public void Dispose()
 {
     try
     {
         if (_httpContext != null &&
             _httpContext.TryGetPropertyValue("Response", out object response) &&
             response.TryGetPropertyValue("StatusCode", out object statusCode))
         {
             _scope?.Span?.SetTag("http.status_code", statusCode.ToString());
         }
     }
     finally
     {
         _scope?.Dispose();
     }
 }
        public void Dispose_ListWithOneItem_DisposesItem()
        {
            // Arrange
            var scope = new Scope();

            var disposable = new DisposableObject();

            Assert.IsFalse(disposable.IsDisposedOnce, "Test setup");

            var disposables = new List<IDisposable> { disposable };

            scope.RegisterForDisposal(disposable);

            // Act
            scope.Dispose();

            // Assert
            Assert.IsTrue(disposable.IsDisposedOnce);
        }
Exemple #22
0
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState GetResponse_OnMethodBegin <TTarget>(TTarget instance)
        {
            if (instance is HttpWebRequest request && IsTracingEnabled(request))
            {
                Tracer tracer = Tracer.Instance;

                // Check if any headers were injected by a previous call to GetRequestStream
                var spanContext = SpanContextPropagator.Instance.Extract(request.Headers.Wrap());

                // If this operation creates the trace, then we need to re-apply the sampling priority
                bool setSamplingPriority = spanContext?.SamplingPriority != null && tracer.ActiveScope == null;

                Scope scope = null;

                try
                {
                    scope = ScopeFactory.CreateOutboundHttpScope(tracer, request.Method, request.RequestUri, IntegrationId, out _, spanContext?.TraceId, spanContext?.SpanId);

                    if (scope != null)
                    {
                        if (setSamplingPriority && spanContext?.SamplingPriority is not null)
                        {
                            scope.Span.SetTraceSamplingPriority(spanContext.SamplingPriority.Value);
                        }

                        // add distributed tracing headers to the HTTP request
                        SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap());

                        tracer.TracerManager.Telemetry.IntegrationGeneratedSpan(IntegrationId);

                        return(new CallTargetState(scope));
                    }
                }
                catch
                {
                    scope?.Dispose();
                    throw;
                }
            }

            return(CallTargetState.GetDefault());
        }
 /// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 public void Dispose()
 {
     try
     {
         // sometimes, if an exception was unhandled in user code, status code is set to 500 later in the pipeline,
         // so it is still 200 here. if there was an unhandled exception, always set status code to 500.
         if (_scope?.Span?.Error == true)
         {
             _scope?.Span?.SetTag(Tags.HttpStatusCode, "500");
         }
         else if (_httpContext != null)
         {
             _scope?.Span?.SetTag(Tags.HttpStatusCode, _httpContext.Response.StatusCode.ToString());
         }
     }
     finally
     {
         _scope?.Dispose();
     }
 }
        public void Dispose_MultipleItems_DisposesAllItems()
        {
            // Arrange
            var scope = new Scope();

            var disposables = new List<DisposableObject> 
            { 
                new DisposableObject(),
                new DisposableObject(),
                new DisposableObject()
            };

            disposables.ForEach(scope.RegisterForDisposal);

            // Act
            scope.Dispose();

            // Assert
            Assert.IsTrue(disposables.All(d => d.IsDisposedOnce));
        }
Exemple #25
0
        private void OnBeginRequest(object sender, EventArgs eventArgs)
        {
            Scope scope = null;

            try
            {
                if (!TryGetContext(sender, out var httpContext))
                {
                    return;
                }

                SpanContext propagatedContext = null;

                if (Tracer.Instance.ActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers = httpContext.Request.Headers.Wrap();
                        propagatedContext = SpanContextPropagator.Instance.Extract(headers);
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorException("Error extracting propagated HTTP headers.", ex);
                    }
                }

                scope = Tracer.Instance.StartActive(_operationName, propagatedContext);
                httpContext.Items[_httpContextDelegateKey] = HttpContextSpanIntegrationDelegate.CreateAndBegin(httpContext, scope);
            }
            catch (Exception ex)
            {
                // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case...
                scope?.Dispose();

                Log.ErrorException("Datadog ASP.NET HttpModule instrumentation error", ex);
            }
        }
        private static object ApplyResolveScope(InitializationContext context, Func<object> getInstance)
        {
            var threadLocal = (ThreadLocal<Scope>)context.Registration.Container.GetItem(Key);

            var original = threadLocal.Value;
            var current = new Scope();

            try
            {
                threadLocal.Value = current;
                return getInstance();
            }
            finally
            {
                try
                {
                    current.Dispose();
                }
                finally
                {
                    threadLocal.Value = original;
                }
            }
        }
 public override void DisposeScope()
 {
     _scope?.Dispose();
 }
        public void Dispose_RecursiveResolveTriggeredDuringEndScopeAction_ThrowsDescriptiveException()
        {
            // Arrange
            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<IPlugin>(() =>
            {
                scope.WhenScopeEnds(() =>
                {
                    container.GetInstance<IPlugin>();
                });

                return new DisposablePlugin();
            });

            container.GetInstance<IPlugin>();

            // Act
            Action action = () => scope.Dispose();

            // Assert
            AssertThat.ThrowsWithExceptionMessageContains<ActivationException>(@"
                The registered delegate for type IPlugin threw an exception. A recursive registration of 
                Action or IDisposable instances was detected during disposal of the scope. 
                This is possibly caused by a component that is directly or indirectly depending on itself"
                .TrimInside(),
                action);
        }
        public void Dispose_WithThrowingAction_StillDisposesInstance()
        {
            // Arrange
            bool disposed = false;

            var scope = new Scope();

            scope.WhenScopeEnds(() =>
            {
                throw new Exception();
            });

            scope.RegisterForDisposal(new DisposableObject(_ =>
            {
                disposed = true;
            }));

            try
            {
                // Act
                scope.Dispose();

                // Assert
                Assert.Fail("Exception expected.");
            }
            catch
            {
                Assert.IsTrue(disposed);
            }
        }
        public void Dispose_RecursiveResolveTriggeredInDispose_ThrowsDescriptiveException()
        {
            // Arrange
            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<IPlugin>(() =>
            {
                var plugin = new DisposablePlugin(disposing: _ =>
                {
                    // Recursive dependency
                    // Although really bad practice, this must not cause an infinit spin or a stackoverflow.
                    container.GetInstance<IPlugin>();
                });

                scope.RegisterForDisposal(plugin);

                return plugin;
            });

            container.GetInstance<IPlugin>();

            // Act
            Action action = () => scope.Dispose();

            // Assert
            AssertThat.ThrowsWithExceptionMessageContains<ActivationException>(@"
                The registered delegate for type IPlugin threw an exception. A recursive registration of 
                Action or IDisposable instances was detected during disposal of the scope. 
                This is possibly caused by a component that is directly or indirectly depending on itself"
                .TrimInside(),
                action);
        }
        public void Dispose_WithMultipleItemsThatThrow_StillDisposesAllItems()
        {
            // Arrange
            var scope = new Scope();

            var disposables = new List<DisposableObject> 
            { 
                new DisposableObject(new Exception()),
                new DisposableObject(new Exception()),
                new DisposableObject(new Exception())
            };

            disposables.ForEach(scope.RegisterForDisposal);

            try
            {
                // Act
                scope.Dispose();

                // Assert
                Assert.Fail("Exception was expected to bubble up.");
            }
            catch
            {
                Assert.IsTrue(disposables.All(d => d.IsDisposedOnce));
            }
        }
Exemple #32
0
 public void Dispose()
 {
     _scope?.Dispose();
     _container?.Dispose();
 }
        public void Dispose_ScopedInstanceResolvedDuringDisposingScope_CreatesInstanceWithExpectedLifestyle()
        {
            // Arrange
            IPlugin plugin1 = null;
            IPlugin plugin2 = null;

            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<IPlugin>(() => new DisposablePlugin(), scopedLifestyle);

            container.Register<DisposableObject>(() => new DisposableObject(disposing: _ =>
            {
                plugin1 = container.GetInstance<IPlugin>();
                plugin2 = container.GetInstance<IPlugin>();
            }), scopedLifestyle);

            container.GetInstance<DisposableObject>();

            // Act
            scope.Dispose();

            // Assert
            Assert.IsNotNull(plugin1);
            Assert.AreSame(plugin1, plugin2);
        }
        public void Dispose_MultipleItems_DisposesAllItemsInReversedOrder()
        {
            // Arrange
            var scope = new Scope();

            var disposedItems = new List<DisposableObject>();

            var disposables = new List<DisposableObject> 
            { 
                new DisposableObject(disposedItems.Add),
                new DisposableObject(disposedItems.Add),
                new DisposableObject(disposedItems.Add)
            };

            disposables.ForEach(scope.RegisterForDisposal);

            // Act
            scope.Dispose();

            disposedItems.Reverse();

            // Assert
            Assert.IsTrue(disposedItems.SequenceEqual(disposables));
        }
        public void Dispose_WithMultipleItemsThatThrow_WillBubbleUpTheLastThrownException()
        {
            // Arrange
            var scope = new Scope();

            Exception lastThrownException = new Exception();

            var disposables = new List<DisposableObject> 
            { 
                // Since the objects are disposed in reverse order, the first object is disposed last, and
                // this exception is expected to bubble up.
                new DisposableObject(exceptionToThrow: lastThrownException),
                new DisposableObject(exceptionToThrow: new Exception()),
                new DisposableObject(exceptionToThrow: new Exception()),
                new DisposableObject(),
                new DisposableObject(exceptionToThrow: new Exception()),
                new DisposableObject(exceptionToThrow: new Exception())
            };

            disposables.ForEach(scope.RegisterForDisposal);

            try
            {
                // Act
                scope.Dispose();

                // Assert
                Assert.Fail("Exception was expected to bubble up.");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(object.ReferenceEquals(lastThrownException, ex));
            }
        }
        public void WhenScopeEnds_CalledOnDisposedScope_ThrowsObjectDisposedException()
        {
            // Arrange
            var scope = new Scope();

            scope.Dispose();

            // Act
            Action action = () => scope.WhenScopeEnds(() => { });

            // Assert
            AssertThat.Throws<ObjectDisposedException>(action,
                "Calling WhenScopeEnds should throw an ObjectDisposedException.");
        }
        public void RegisterForDisposal_CalledOnDisposedScope_ThrowsObjectDisposedException()
        {
            // Arrange
            var scope = new Scope();

            scope.Dispose();

            // Act
            Action action = () => scope.RegisterForDisposal(new DisposableObject());

            // Assert
            AssertThat.Throws<ObjectDisposedException>(action,
                "Calling RegisterForDisposal should throw an ObjectDisposedException.");
        }
        public void Dispose_WhenDisposeEndsActionRegisteredDuringDisposal_CallsTheRegisteredDelegate()
        {
            // Arrange
            bool actionCalled = false;

            var disposable = new DisposableObject();

            var scope = new Scope();

            var container = new Container();

            container.Register<DisposableObject>(() => disposable, new FakeScopedLifestyle(scope));
            container.RegisterInitializer<DisposableObject>(instance =>
            {
                scope.WhenScopeEnds(() => actionCalled = true);
            });

            scope.WhenScopeEnds(() => container.GetInstance<DisposableObject>());

            // Act
            scope.Dispose();

            // Assert
            Assert.IsTrue(actionCalled);
        }
        public void Dispose_ScopedItemResolvedDuringScopeEndAction_GetsDisposed()
        {
            // Arrange
            var disposable = new DisposableObject();

            var scope = new Scope();

            var container = new Container();

            container.Register<DisposableObject>(() => disposable, new FakeScopedLifestyle(scope));

            scope.WhenScopeEnds(() => container.GetInstance<DisposableObject>());

            // Act
            scope.Dispose();

            // Assert
            Assert.IsTrue(disposable.IsDisposedOnce);
        }
        public void Dispose_RecursiveResolveTriggeredDuringEndScopeAction_StillDisposesRegisteredDisposables()
        {
            // Arrange
            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            var disposable = new DisposableObject();

            scope.RegisterForDisposal(disposable);

            container.Register<IPlugin>(() =>
            {
                scope.WhenScopeEnds(() =>
                {
                    container.GetInstance<IPlugin>();
                });

                return new DisposablePlugin();
            });

            container.GetInstance<IPlugin>();

            try
            {
                // Act
                scope.Dispose();

                Assert.Fail("Exception expected.");
            }
            catch
            {
                // Assert
                Assert.IsTrue(disposable.IsDisposedOnce,
                    "Even though there was a recursion detected when executing Action delegates, all " +
                    "registered disposables should still get disposed.");
            }
        }
 public void Dispose()
 {
     _scope?.Dispose();
 }
        public void GetInstance_CalledOnADisposedScope_ThrowsObjectDisposedException()
        {
            // Arrange
            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<IPlugin>(() => new DisposablePlugin(), scopedLifestyle);

            container.GetInstance<IPlugin>();

            scope.Dispose();

            // Act
            Action action = () => container.GetInstance<IPlugin>();

            // Assert
            AssertThat.ThrowsWithExceptionMessageContains<ActivationException>(
                CannotAccessADisposedObjectMessage,
                action);
        }
Exemple #43
0
        private void OnBeginRequest(object sender, EventArgs eventArgs)
        {
            Scope scope = null;

            try
            {
                var tracer = Tracer.Instance;

                if (!tracer.Settings.IsIntegrationEnabled(IntegrationId))
                {
                    // integration disabled
                    return;
                }

                var httpContext = (sender as HttpApplication)?.Context;

                if (httpContext == null)
                {
                    return;
                }

                HttpRequest httpRequest       = httpContext.Request;
                SpanContext propagatedContext = null;
                var         tagsFromHeaders   = Enumerable.Empty <KeyValuePair <string, string> >();
                var         propagator        = tracer.Propagator;

                if (tracer.ActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers = httpRequest.Headers.Wrap();
                        propagatedContext = propagator.Extract(headers);
                        tagsFromHeaders   = headers.ExtractHeaderTags(tracer.Settings.HeaderTags);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Error extracting propagated HTTP headers.");
                    }
                }

                string host       = httpRequest.Headers.Get("Host");
                string httpMethod = httpRequest.HttpMethod.ToUpperInvariant();
                string url        = httpRequest.RawUrl.ToLowerInvariant();

                var tags = new WebTags();
                scope = tracer.StartActiveWithTags(_requestOperationName, propagatedContext, tags: tags);
                // Leave resourceName blank for now - we'll update it in OnEndRequest
                scope.Span.DecorateWebServerSpan(resourceName: null, httpMethod, host, url, tags, tagsFromHeaders);

                tags.SetAnalyticsSampleRate(IntegrationId, tracer.Settings, enabledWithGlobalSetting: true);

                httpContext.Items[_httpContextScopeKey] = scope;

                // Decorate the incoming HTTP Request with distributed tracing headers
                // in case the next processor cannot access the stored Scope
                // (e.g. WCF being hosted in IIS)
                propagator.Inject(scope.Span.Context, httpRequest.Headers.Wrap());
            }
            catch (Exception ex)
            {
                // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case...
                scope?.Dispose();
                Log.Error(ex, "Datadog ASP.NET HttpModule instrumentation error");
            }
        }
        public void GetInstance_ResolvingScopedInstanceWhileDifferentThreadIsVerifying_DoesNotResolveInstanceFromVerificationScope()
        {
            // Arrange
            DisposablePlugin verifiedPlugin = null;
            DisposablePlugin backgroundResolvedPlugin = null;
            Task task = null;

            var container = new Container();

            var scope = new Scope();
            var lifestyle = new FakeScopedLifestyle(scope);

            container.Register<IPlugin, DisposablePlugin>(lifestyle);
            container.RegisterInitializer<DisposablePlugin>(p =>
            {
                verifiedPlugin = p;

                // Resolve on a different thread (so not during verification)
                task = Task.Run(() =>
                {
                    backgroundResolvedPlugin = (DisposablePlugin)container.GetInstance<IPlugin>();
                });

                Thread.Sleep(150);
            });

            // Act
            container.Verify();

            task.Wait();

            // Assert
            Assert.IsFalse(backgroundResolvedPlugin.IsDisposedOnce,
                "Since this instance isn't resolved during verification, but within an active scope, " +
                "The instance should not have been disposed here.");

            scope.Dispose();

            Assert.IsTrue(backgroundResolvedPlugin.IsDisposedOnce, "Now it should have been disposed.");
        }
 public void Dispose()
 {
     _metricWrapper?.Dispose();
     _sfxScope?.Dispose();
 }
 public void Dispose()
 {
     Scope?.Dispose();
 }
        public void Dispose_ExceptionThrownDuringDisposalAfterResolvingNewInstance_DoesNotCallAnyNewActions()
        {
            // Arrange
            bool scopeEndActionCalled = false;

            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<IPlugin>(() => new DisposablePlugin());
            container.RegisterInitializer<IPlugin>(
                plugin => scope.WhenScopeEnds(() => scopeEndActionCalled = true));

            container.Register<DisposableObject>(() => new DisposableObject(_ =>
            {
                container.GetInstance<IPlugin>();
                throw new Exception("Bang!");
            }), scopedLifestyle);

            try
            {
                // Act
                scope.Dispose();

                // Assert
                Assert.Fail("Exception expected.");
            }
            catch
            {
                Assert.IsFalse(scopeEndActionCalled,
                    "In case of an exception, no actions will be further executed. This lowers the change " +
                    "the new exceptions are thrown from other actions that cover up the original exception.");
            }
        }
        public void Dispose_ScopedInstanceResolvedDuringDisposingScope_DisposesThisInstanceLast()
        {
            // Arrange
            var disposedObjects = new List<object>();

            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<IPlugin>(() => new DisposablePlugin(disposedObjects.Add), scopedLifestyle);
            container.Register<IDisposable>(() => new DisposableObject(disposedObjects.Add), scopedLifestyle);
            container.Register<DisposableObject>(() => new DisposableObject(_ =>
            {
                container.GetInstance<IPlugin>();
            }), scopedLifestyle);

            container.GetInstance<IDisposable>();
            container.GetInstance<DisposableObject>();

            // Act
            scope.Dispose();

            // Assert
            AssertThat.IsInstanceOfType(typeof(DisposablePlugin), disposedObjects.Last(), "Since the disposable logger is requested during disposal of the scope, it should be " +
                "disposed after all other already created services have been disposed. " +
                "In the given case, disposing DisposableLogger before the IDisposable registration becomes " +
                "a problem when that registration starts using ILogger in its dispose method as well.");
        }
        public void ShouldThrowExceptionWhenEndingNonCurrentScope()
        {
            var container = CreateContainer();

            using (container.BeginScope())
            {
                var scope = new Scope(container.ScopeManagerProvider.GetScopeManager(container), null);
                Assert.Throws<InvalidOperationException>(() => scope.Dispose());
            }
        }
        public void Dispose_InstanceResolvedDuringDisposingScopeRegisteringEndAction_CallsThisAction()
        {
            // Arrange
            bool actionCalled = false;

            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<DisposableObject>(() => new DisposableObject(_ =>
            {
                container.GetInstance<IPlugin>();
            }), scopedLifestyle);

            container.Register<IPlugin>(() =>
            {
                scope.WhenScopeEnds(() => actionCalled = true);
                return new DisposablePlugin();
            }, Lifestyle.Transient);

            container.GetInstance<DisposableObject>();

            // Act
            scope.Dispose();

            // Assert
            Assert.IsTrue(actionCalled);
        }
        public void Dispose_ExceptionThrownDuringDisposalAfterResolvingNewInstance_DisposesThatInstance()
        {
            // Arrange
            bool newlyResolvedInstanceDisposed = false;

            var scope = new Scope();

            var scopedLifestyle = new FakeScopedLifestyle(scope);

            var container = new Container();

            container.Register<IPlugin>(
                () => new DisposablePlugin(disposing: _ => newlyResolvedInstanceDisposed = true),
                scopedLifestyle);

            container.Register<DisposableObject>(() => new DisposableObject(disposing: _ =>
                {
                    container.GetInstance<IPlugin>();
                    throw new Exception("Bang!");
                }), scopedLifestyle);

            container.GetInstance<DisposableObject>();

            try
            {
                // Act
                scope.Dispose();

                // Assert
                Assert.Fail("Exception expected.");
            }
            catch
            {
                Assert.IsTrue(newlyResolvedInstanceDisposed);
            }
        }
        public void Dispose_RegisteredActionAndRegisteredDisposableObject_CallsActionFirst()
        {
            // Arrange
            int actionCount = 0;
            int disposeCount = 0;

            var scope = new Scope();

            scope.RegisterForDisposal(new DisposableObject(_ =>
            {
                Assert.AreEqual(2, actionCount);
                disposeCount++;
            }));

            scope.WhenScopeEnds(() =>
            {
                Assert.AreEqual(0, disposeCount);
                actionCount++;
            });

            scope.WhenScopeEnds(() =>
            {
                Assert.AreEqual(0, disposeCount);
                actionCount++;
            });

            scope.RegisterForDisposal(new DisposableObject(_ =>
            {
                Assert.AreEqual(2, actionCount);
                disposeCount++;
            }));

            // Act
            scope.Dispose();

            // Assert
            Assert.AreEqual(2, actionCount);
            Assert.AreEqual(2, disposeCount);
        }
        public static bool EndInvokeAction(
            object asyncControllerActionInvoker,
            object asyncResult,
            int opCode,
            int mdToken,
            long moduleVersionPtr)
        {
            if (asyncControllerActionInvoker == null)
            {
                throw new ArgumentNullException(nameof(asyncControllerActionInvoker));
            }

            Scope scope       = null;
            var   httpContext = HttpContext.Current;

            try
            {
                scope = httpContext?.Items[HttpContextKey] as Scope;
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error instrumenting method {0}", $"{AsyncActionInvokerTypeName}.EndInvokeAction()");
            }

            Func <object, object, bool> instrumentedMethod;

            try
            {
                var asyncActionInvokerType = asyncControllerActionInvoker.GetInstrumentedInterface(AsyncActionInvokerTypeName);

                instrumentedMethod = MethodBuilder <Func <object, object, bool> >
                                     .Start(moduleVersionPtr, mdToken, opCode, nameof(EndInvokeAction))
                                     .WithConcreteType(asyncActionInvokerType)
                                     .WithParameters(asyncResult)
                                     .WithNamespaceAndNameFilters(ClrNames.Bool, ClrNames.IAsyncResult)
                                     .Build();
            }
            catch (Exception ex)
            {
                Log.ErrorRetrievingMethod(
                    exception: ex,
                    moduleVersionPointer: moduleVersionPtr,
                    mdToken: mdToken,
                    opCode: opCode,
                    instrumentedType: AsyncActionInvokerTypeName,
                    methodName: nameof(EndInvokeAction),
                    instanceType: asyncControllerActionInvoker.GetType().AssemblyQualifiedName);
                throw;
            }

            try
            {
                // call the original method, inspecting (but not catching) any unhandled exceptions
                return(instrumentedMethod(asyncControllerActionInvoker, asyncResult));
            }
            catch (Exception ex)
            {
                scope?.Span.SetException(ex);
                throw;
            }
            finally
            {
                scope?.Dispose();
            }
        }