diff --git a/src/Sentry.AspNetCore/SentryMiddleware.cs b/src/Sentry.AspNetCore/SentryMiddleware.cs index 516ce1d235..82d2605cf5 100644 --- a/src/Sentry.AspNetCore/SentryMiddleware.cs +++ b/src/Sentry.AspNetCore/SentryMiddleware.cs @@ -18,7 +18,7 @@ namespace Sentry.AspNetCore internal class SentryMiddleware { private readonly RequestDelegate _next; - private readonly IHub _sentry; + private readonly Func _hubAccessor; private readonly SentryAspNetCoreOptions _options; private readonly IHostingEnvironment _hostingEnvironment; private readonly ILogger _logger; @@ -32,7 +32,7 @@ internal static readonly (string Name, string Version) NameAndVersion /// Initializes a new instance of the class. /// /// The next. - /// The sentry. + /// The sentry Hub accessor. /// The options for this integration /// The hosting environment. /// Sentry logger. @@ -43,13 +43,13 @@ internal static readonly (string Name, string Version) NameAndVersion /// public SentryMiddleware( RequestDelegate next, - IHub sentry, + Func hubAccessor, IOptions options, IHostingEnvironment hostingEnvironment, ILogger logger) { _next = next ?? throw new ArgumentNullException(nameof(next)); - _sentry = sentry ?? throw new ArgumentNullException(nameof(sentry)); + _hubAccessor = hubAccessor ?? throw new ArgumentNullException(nameof(hubAccessor)); _options = options?.Value; _hostingEnvironment = hostingEnvironment; _logger = logger; @@ -62,20 +62,21 @@ public SentryMiddleware( /// public async Task InvokeAsync(HttpContext context) { - if (!_sentry.IsEnabled) + var hub = _hubAccessor(); + if (!hub.IsEnabled) { await _next(context).ConfigureAwait(false); return; } - using (_sentry.PushAndLockScope()) + using (hub.PushAndLockScope()) { if (_options?.IncludeRequestPayload == true) { context.Request.EnableRewind(); } - _sentry.ConfigureScope(scope => + hub.ConfigureScope(scope => { // At the point lots of stuff from the request are not yet filled // Identity for example is added later on in the pipeline @@ -110,7 +111,7 @@ void CaptureException(Exception e) _logger?.LogTrace("Sending event '{SentryEvent}' to Sentry.", evt); - var id = _sentry.CaptureEvent(evt); + var id = hub.CaptureEvent(evt); _logger?.LogInformation("Event '{id}' queued.", id); } diff --git a/src/Sentry.Extensions.Logging/Extensions/DependencyInjection/ServiceCollectionExtensions.cs b/src/Sentry.Extensions.Logging/Extensions/DependencyInjection/ServiceCollectionExtensions.cs index 131afc8677..8417e7c8dc 100644 --- a/src/Sentry.Extensions.Logging/Extensions/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Sentry.Extensions.Logging/Extensions/DependencyInjection/ServiceCollectionExtensions.cs @@ -1,3 +1,4 @@ +using System; using System.ComponentModel; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -26,26 +27,22 @@ public static IServiceCollection AddSentry(this IServiceCollection ser services.TryAddSingleton(); - services.TryAddSingleton(c => + services.TryAddTransient(c => c.GetRequiredService()); + services.TryAddTransient(c => c.GetRequiredService>()()); + + services.TryAddSingleton>(c => { var options = c.GetRequiredService>().Value; - IHub hub; if (options.InitializeSdk) { - hub = c.GetRequiredService(); - } - else - { - // Access to whatever the SentrySdk points to (disabled or initialized via SentrySdk.Init) - hub = HubAdapter.Instance; + var hub = c.GetRequiredService(); + SentrySdk.UseHub(hub); } - return hub; + return () => HubAdapter.Instance; }); - services.TryAddSingleton(c => c.GetService()); - return services; } } diff --git a/src/Sentry.Extensions.Logging/SentryLoggerFactoryExtensions.cs b/src/Sentry.Extensions.Logging/SentryLoggerFactoryExtensions.cs index cb7ba3c582..2bbb041fc0 100644 --- a/src/Sentry.Extensions.Logging/SentryLoggerFactoryExtensions.cs +++ b/src/Sentry.Extensions.Logging/SentryLoggerFactoryExtensions.cs @@ -42,6 +42,7 @@ public static ILoggerFactory AddSentry( if (options.InitializeSdk) { hub = new OptionalHub(options); + SentrySdk.UseHub(hub); } else { diff --git a/src/Sentry/Internal/OptionalHub.cs b/src/Sentry/Internal/OptionalHub.cs index 5804b79d44..d0fb3ac30f 100644 --- a/src/Sentry/Internal/OptionalHub.cs +++ b/src/Sentry/Internal/OptionalHub.cs @@ -11,7 +11,6 @@ namespace Sentry.Internal internal class OptionalHub : IHub, IDisposable { private readonly IHub _hub; - private readonly IDisposable _disposable; public bool IsEnabled => _hub.IsEnabled; @@ -24,14 +23,13 @@ public OptionalHub(SentryOptions options) if (!Dsn.TryParse(DsnLocator.FindDsnStringOrDisable(), out var dsn)) { options.DiagnosticLogger?.LogWarning("Init was called but no DSN was provided nor located. Sentry SDK will be disabled."); - _hub = HubAdapter.Instance; + _hub = DisabledHub.Instance; return; } options.Dsn = dsn; } _hub = new Hub(options); - _disposable = SentrySdk.UseHub(_hub); } public SentryId CaptureEvent(SentryEvent evt, Scope scope = null) => _hub.CaptureEvent(evt, scope); @@ -50,6 +48,6 @@ public OptionalHub(SentryOptions options) public SentryId LastEventId => _hub.LastEventId; - public void Dispose() => _disposable?.Dispose(); + public void Dispose() => (_hub as IDisposable)?.Dispose(); } } diff --git a/test/Sentry.AspNetCore.Tests/MiddlewareLoggerIntegration.cs b/test/Sentry.AspNetCore.Tests/MiddlewareLoggerIntegration.cs index 4814c922f4..ccfb52a90c 100644 --- a/test/Sentry.AspNetCore.Tests/MiddlewareLoggerIntegration.cs +++ b/test/Sentry.AspNetCore.Tests/MiddlewareLoggerIntegration.cs @@ -21,6 +21,7 @@ private class Fixture : IDisposable { public RequestDelegate RequestDelegate { get; set; } = _ => Task.CompletedTask; public IHub Hub { get; set; } + public Func HubAccessor { get; set; } public ISentryClient Client { get; set; } = Substitute.For(); public ISystemClock Clock { get; set; } = Substitute.For(); public SentryAspNetCoreOptions Options { get; set; } = new SentryAspNetCoreOptions(); @@ -33,6 +34,7 @@ private class Fixture : IDisposable public Fixture() { + HubAccessor = () => Hub; var loggingOptions = new SentryLoggingOptions { InitializeSdk = false, @@ -51,7 +53,7 @@ public Fixture() public SentryMiddleware GetSut() => new SentryMiddleware( RequestDelegate, - Hub, + HubAccessor, Microsoft.Extensions.Options.Options.Create(Options), HostingEnvironment, MiddlewareLogger); diff --git a/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs b/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs index bf0f4e1813..5031b9a8c4 100644 --- a/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs +++ b/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs @@ -19,6 +19,7 @@ private class Fixture { public RequestDelegate RequestDelegate { get; set; } = _ => Task.CompletedTask; public IHub Hub { get; set; } = Substitute.For(); + public Func HubAccessor { get; set; } public SentryAspNetCoreOptions Options { get; set; } = new SentryAspNetCoreOptions(); public IHostingEnvironment HostingEnvironment { get; set; } = Substitute.For(); public ILogger Logger { get; set; } = Substitute.For>(); @@ -27,6 +28,7 @@ private class Fixture public Fixture() { + HubAccessor = () => Hub; Hub.IsEnabled.Returns(true); HttpContext.Features.Returns(FeatureCollection); } @@ -34,7 +36,7 @@ public Fixture() public SentryMiddleware GetSut() => new SentryMiddleware( RequestDelegate, - Hub, + HubAccessor, Microsoft.Extensions.Options.Options.Create(Options), HostingEnvironment, Logger); @@ -340,11 +342,11 @@ public void Ctor_NullRequestDelegate_ThrowsArgumentNullException() } [Fact] - public void Ctor_NullHub_ThrowsArgumentNullException() + public void Ctor_NullHubAccessor_ThrowsArgumentNullException() { - _fixture.Hub = null; + _fixture.HubAccessor = null; var ex = Assert.Throws(() => _fixture.GetSut()); - Assert.Equal("sentry", ex.ParamName); + Assert.Equal("hubAccessor", ex.ParamName); } [Fact]