diff --git a/benchmarks/Sentry.Benchmarks/BenchmarkDotNet.Artifacts/results/MvvmBenchmarks-report-github.md b/benchmarks/Sentry.Benchmarks/BenchmarkDotNet.Artifacts/results/MvvmBenchmarks-report-github.md new file mode 100644 index 0000000000..5726a125c2 --- /dev/null +++ b/benchmarks/Sentry.Benchmarks/BenchmarkDotNet.Artifacts/results/MvvmBenchmarks-report-github.md @@ -0,0 +1,15 @@ +``` + +BenchmarkDotNet v0.13.12, macOS 15.4.1 (24E263) [Darwin 24.4.0] +Apple M2 Max, 1 CPU, 12 logical and 12 physical cores +.NET SDK 9.0.203 + [Host] : .NET 9.0.4 (9.0.425.16305), Arm64 RyuJIT AdvSIMD + DefaultJob : .NET 9.0.4 (9.0.425.16305), Arm64 RyuJIT AdvSIMD + + +``` +| Method | ResolveOptionsWithServiceProvider | Mean | Error | StdDev | Median | Gen0 | Gen1 | Allocated | +|----------------- |---------------------------------- |---------:|---------:|---------:|---------:|--------:|-------:|----------:| +| **'Build MAUI App'** | **Directly** | **494.3 μs** | **19.62 μs** | **53.38 μs** | **476.0 μs** | **12.6953** | **2.9297** | **105.13 KB** | +| **'Build MAUI App'** | **ServiceProvider** | **488.1 μs** | **8.56 μs** | **12.55 μs** | **486.6 μs** | **15.6250** | **3.9063** | **129.52 KB** | +| **'Build MAUI App'** | **InvokeConfigOptions** | **499.5 μs** | **9.93 μs** | **22.21 μs** | **501.9 μs** | **12.6953** | **3.9063** | **110.23 KB** | diff --git a/benchmarks/Sentry.Benchmarks/MvvmBenchmarks.cs b/benchmarks/Sentry.Benchmarks/MvvmBenchmarks.cs new file mode 100644 index 0000000000..8b32b34d83 --- /dev/null +++ b/benchmarks/Sentry.Benchmarks/MvvmBenchmarks.cs @@ -0,0 +1,24 @@ +using BenchmarkDotNet.Attributes; +using Sentry; +using Sentry.Maui; + +public class MvvmBenchmarks +{ + [Params(RegisterEventBinderMethod.ServiceProvider, RegisterEventBinderMethod.InvokeConfigOptions, RegisterEventBinderMethod.Directly)] + public RegisterEventBinderMethod ResolveOptionsWithServiceProvider; + + [Benchmark(Description = "Build MAUI App")] + public void BuildMauiAppBenchmark() + { + var appBuilder = MauiApp.CreateBuilder() + // This adds Sentry to your Maui application + .UseSentry(options => + { + // The DSN is the only required option. + options.Dsn = DsnSamples.ValidDsn; + // Automatically create traces for async relay commands in the MVVM Community Toolkit + options.AddCommunityToolkitIntegration(); + }, ResolveOptionsWithServiceProvider); + appBuilder.Build(); + } +} diff --git a/benchmarks/Sentry.Benchmarks/Sentry.Benchmarks.csproj b/benchmarks/Sentry.Benchmarks/Sentry.Benchmarks.csproj index bdb8ed918a..2d9fa82fbf 100644 --- a/benchmarks/Sentry.Benchmarks/Sentry.Benchmarks.csproj +++ b/benchmarks/Sentry.Benchmarks/Sentry.Benchmarks.csproj @@ -2,8 +2,9 @@ Exe - net8.0 + net9.0 false + true @@ -13,6 +14,8 @@ + + diff --git a/src/Sentry.Maui/SentryMauiAppBuilderExtensions.cs b/src/Sentry.Maui/SentryMauiAppBuilderExtensions.cs index 83e1bd7740..fd28d8afbc 100644 --- a/src/Sentry.Maui/SentryMauiAppBuilderExtensions.cs +++ b/src/Sentry.Maui/SentryMauiAppBuilderExtensions.cs @@ -11,6 +11,25 @@ // ReSharper disable once CheckNamespace namespace Microsoft.Maui.Hosting; +/// +/// An enum +/// +public enum RegisterEventBinderMethod +{ + /// + /// Registers the services directly... unable to inject the MvvM integration this way + /// + Directly, + /// + /// Register with the service provider + /// + ServiceProvider, + /// + /// Instantiate the options directly and invoke the config callback on it + /// + InvokeConfigOptions +} + /// /// Sentry extensions for . /// @@ -39,9 +58,10 @@ public static MauiAppBuilder UseSentry(this MauiAppBuilder builder, string dsn) /// /// The builder. /// An action to configure the options. + /// /// The . public static MauiAppBuilder UseSentry(this MauiAppBuilder builder, - Action? configureOptions) + Action? configureOptions, RegisterEventBinderMethod eventBinderRegistrationMethod = RegisterEventBinderMethod.ServiceProvider) { var services = builder.Services; @@ -57,14 +77,43 @@ public static MauiAppBuilder UseSentry(this MauiAppBuilder builder, services.AddSingleton(); // Resolve the configured options and register any element event binders from these - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var options = serviceProvider.GetRequiredService>().Value; - services.TryAddSingleton(options); // Ensure this doesn't get resolved again in AddSentry - foreach (var eventBinder in options.DefaultEventBinders) + switch (eventBinderRegistrationMethod) { - eventBinder.Register(services); + case RegisterEventBinderMethod.Directly: + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + break; + case RegisterEventBinderMethod.InvokeConfigOptions: + var options = new SentryMauiOptions(); + configureOptions?.Invoke(options); + services.TryAddSingleton(options); // Ensure this doesn't get resolved again in AddSentry + foreach (var eventBinder in options.DefaultEventBinders) + { + eventBinder.Register(services); + } + break; + case RegisterEventBinderMethod.ServiceProvider: + IServiceProvider serviceProvider = services.BuildServiceProvider(); + options = serviceProvider.GetRequiredService>().Value; + services.TryAddSingleton(options); // Ensure this doesn't get resolved again in AddSentry + foreach (var eventBinder in options.DefaultEventBinders) + { + eventBinder.Register(services); + } + break; } + // // Resolve the configured options and register any element event binders from these + // IServiceProvider serviceProvider = services.BuildServiceProvider(); + // var options = serviceProvider.GetRequiredService>().Value; + // services.TryAddSingleton(options); // Ensure this doesn't get resolved again in AddSentry + // foreach (var eventBinder in options.DefaultEventBinders) + // { + // eventBinder.Register(services); + // } + // This is ultimately the class that enables all the MauiElementEventBinders above services.TryAddSingleton();