[di] Expose a detached LoggerProviderBuilder extension on IServiceCollection which may modify services (#4531)
Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com>
This commit is contained in:
parent
2f77b31d9c
commit
0ddbdb4e53
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
* Added an `IServiceCollection.ConfigureOpenTelemetryMeterProvider` overload
|
||||
which may be used to configure `MeterProviderBuilder`s while the
|
||||
`IServiceCollection` is modifiable (before the `IServiceProvider` has been
|
||||
created).
|
||||
([#4517](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4517))
|
||||
|
||||
## 1.5.0-rc.1
|
||||
|
||||
Released 2023-May-25
|
||||
|
|
@ -18,12 +24,6 @@ Released 2023-May-25
|
|||
created).
|
||||
([#4508](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4508))
|
||||
|
||||
* Added an `IServiceCollection.ConfigureOpenTelemetryMeterProvider` overload
|
||||
which may be used to configure `MeterProviderBuilder`s while the
|
||||
`IServiceCollection` is modifiable (before the `IServiceProvider` has been
|
||||
created).
|
||||
([#4517](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4517))
|
||||
|
||||
## 1.5.0-alpha.2
|
||||
|
||||
Released 2023-Mar-31
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
// <copyright file="LoggerProviderServiceCollectionBuilder.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenTelemetry.Internal;
|
||||
|
||||
namespace OpenTelemetry.Logs;
|
||||
|
||||
internal sealed class LoggerProviderServiceCollectionBuilder : LoggerProviderBuilder, ILoggerProviderBuilder
|
||||
{
|
||||
public LoggerProviderServiceCollectionBuilder(IServiceCollection services)
|
||||
{
|
||||
services.ConfigureOpenTelemetryLoggerProvider((sp, builder) => this.Services = null);
|
||||
|
||||
this.Services = services;
|
||||
}
|
||||
|
||||
public IServiceCollection? Services { get; set; }
|
||||
|
||||
public LoggerProvider? Provider => null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override LoggerProviderBuilder AddInstrumentation<TInstrumentation>(Func<TInstrumentation> instrumentationFactory)
|
||||
{
|
||||
Guard.ThrowIfNull(instrumentationFactory);
|
||||
|
||||
this.ConfigureBuilderInternal((sp, builder) =>
|
||||
{
|
||||
builder.AddInstrumentation(instrumentationFactory);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public LoggerProviderBuilder ConfigureServices(Action<IServiceCollection> configure)
|
||||
=> this.ConfigureServicesInternal(configure);
|
||||
|
||||
/// <inheritdoc cref="IDeferredLoggerProviderBuilder.Configure" />
|
||||
public LoggerProviderBuilder ConfigureBuilder(Action<IServiceProvider, LoggerProviderBuilder> configure)
|
||||
=> this.ConfigureBuilderInternal(configure);
|
||||
|
||||
/// <inheritdoc />
|
||||
LoggerProviderBuilder IDeferredLoggerProviderBuilder.Configure(Action<IServiceProvider, LoggerProviderBuilder> configure)
|
||||
=> this.ConfigureBuilderInternal(configure);
|
||||
|
||||
private LoggerProviderBuilder ConfigureBuilderInternal(Action<IServiceProvider, LoggerProviderBuilder> configure)
|
||||
{
|
||||
var services = this.Services
|
||||
?? throw new NotSupportedException("Builder cannot be configured during LoggerProvider construction.");
|
||||
|
||||
services.ConfigureOpenTelemetryLoggerProvider(configure);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private LoggerProviderBuilder ConfigureServicesInternal(Action<IServiceCollection> configure)
|
||||
{
|
||||
Guard.ThrowIfNull(configure);
|
||||
|
||||
var services = this.Services
|
||||
?? throw new NotSupportedException("Services cannot be configured during LoggerProvider construction.");
|
||||
|
||||
configure(services);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,9 +26,7 @@ internal static class OpenTelemetryDependencyInjectionLoggingServiceCollectionEx
|
|||
{
|
||||
/// <summary>
|
||||
/// Registers an action used to configure the OpenTelemetry <see
|
||||
/// cref="LoggerProviderBuilder"/> used to create the <see
|
||||
/// cref="LoggerProvider"/> for the <see cref="IServiceCollection"/> being
|
||||
/// configured.
|
||||
/// cref="LoggerProviderBuilder"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Notes:
|
||||
|
|
@ -36,14 +34,56 @@ internal static class OpenTelemetryDependencyInjectionLoggingServiceCollectionEx
|
|||
/// <item>This is safe to be called multiple times and by library authors.
|
||||
/// Each registered configuration action will be applied
|
||||
/// sequentially.</item>
|
||||
/// <item>A <see cref="LoggerProvider"/> will not be created automatically
|
||||
/// using this method. To begin collecting metrics use the
|
||||
/// <item>A <see cref="LoggerProvider"/> will NOT be created automatically
|
||||
/// using this method. To begin collecting logs use the
|
||||
/// <c>IServiceCollection.AddOpenTelemetry</c> extension in the
|
||||
/// <c>OpenTelemetry.Extensions.Hosting</c> package.</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <param name="services">The <see cref="IServiceCollection" /> to add
|
||||
/// services to.</param>
|
||||
/// <param name="services"><see cref="IServiceCollection" />.</param>
|
||||
/// <param name="configure">Callback action to configure the <see
|
||||
/// cref="LoggerProviderBuilder"/>.</param>
|
||||
/// <returns>The <see cref="IServiceCollection"/> so that additional calls
|
||||
/// can be chained.</returns>
|
||||
public static IServiceCollection ConfigureOpenTelemetryLoggerProvider(
|
||||
this IServiceCollection services,
|
||||
Action<LoggerProviderBuilder> configure)
|
||||
{
|
||||
Guard.ThrowIfNull(services);
|
||||
Guard.ThrowIfNull(configure);
|
||||
|
||||
configure(new LoggerProviderServiceCollectionBuilder(services));
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an action used to configure the OpenTelemetry <see
|
||||
/// cref="LoggerProviderBuilder"/> once the <see cref="IServiceProvider"/>
|
||||
/// is available.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Notes:
|
||||
/// <list type="bullet">
|
||||
/// <item>This is safe to be called multiple times and by library authors.
|
||||
/// Each registered configuration action will be applied
|
||||
/// sequentially.</item>
|
||||
/// <item>A <see cref="LoggerProvider"/> will NOT be created automatically
|
||||
/// using this method. To begin collecting logs use the
|
||||
/// <c>IServiceCollection.AddOpenTelemetry</c> extension in the
|
||||
/// <c>OpenTelemetry.Extensions.Hosting</c> package.</item>
|
||||
/// <item>The supplied configuration delegate is called once the <see
|
||||
/// cref="IServiceProvider"/> is available. Services may NOT be added to a
|
||||
/// <see cref="LoggerProviderBuilder"/> once the <see
|
||||
/// cref="IServiceProvider"/> has been created. Many helper extensions
|
||||
/// register services and may throw if invoked inside the configuration
|
||||
/// delegate. If you don't need access to the <see cref="IServiceProvider"/>
|
||||
/// call <see cref="ConfigureOpenTelemetryLoggerProvider(IServiceCollection,
|
||||
/// Action{LoggerProviderBuilder})"/> instead which is safe to be used with
|
||||
/// helper extensions.</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <param name="services"><see cref="IServiceCollection" />.</param>
|
||||
/// <param name="configure">Callback action to configure the <see
|
||||
/// cref="LoggerProviderBuilder"/>.</param>
|
||||
/// <returns>The <see cref="IServiceCollection"/> so that additional calls
|
||||
|
|
@ -51,19 +91,14 @@ internal static class OpenTelemetryDependencyInjectionLoggingServiceCollectionEx
|
|||
public static IServiceCollection ConfigureOpenTelemetryLoggerProvider(
|
||||
this IServiceCollection services,
|
||||
Action<IServiceProvider, LoggerProviderBuilder> configure)
|
||||
{
|
||||
RegisterBuildAction(services, configure);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
private static void RegisterBuildAction(IServiceCollection services, Action<IServiceProvider, LoggerProviderBuilder> configure)
|
||||
{
|
||||
Guard.ThrowIfNull(services);
|
||||
Guard.ThrowIfNull(configure);
|
||||
|
||||
services.AddSingleton<IConfigureLoggerProviderBuilder>(
|
||||
new ConfigureLoggerProviderBuilderCallbackWrapper(configure));
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
private sealed class ConfigureLoggerProviderBuilderCallbackWrapper : IConfigureLoggerProviderBuilder
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ public sealed class OpenTelemetryBuilder
|
|||
// Note: This enables ILogger integration
|
||||
this.Services.AddLogging().AddOpenTelemetry();
|
||||
|
||||
var builder = new LoggerProviderServiceCollectionBuilder(this.Services);
|
||||
var builder = new LoggerProviderBuilderBase(this.Services);
|
||||
|
||||
configure(builder);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// <copyright file="LoggerProviderServiceCollectionBuilder.cs" company="OpenTelemetry Authors">
|
||||
// <copyright file="LoggerProviderBuilderBase.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
@ -23,20 +23,17 @@ using OpenTelemetry.Internal;
|
|||
namespace OpenTelemetry.Logs;
|
||||
|
||||
/// <summary>
|
||||
/// Contains methods for registering actions into an <see
|
||||
/// cref="IServiceCollection"/> which will be used to build a <see
|
||||
/// cref="LoggerProvider"/> once the <see cref="IServiceProvider"/> is
|
||||
/// available.
|
||||
/// Contains methods for building <see cref="LoggerProvider"/> instances.
|
||||
/// </summary>
|
||||
internal sealed class LoggerProviderServiceCollectionBuilder : LoggerProviderBuilder, ILoggerProviderBuilder
|
||||
internal sealed class LoggerProviderBuilderBase : LoggerProviderBuilder, ILoggerProviderBuilder
|
||||
{
|
||||
private readonly bool allowBuild;
|
||||
private IServiceCollection? services;
|
||||
private readonly LoggerProviderServiceCollectionBuilder innerBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LoggerProviderServiceCollectionBuilder"/> class.
|
||||
/// Initializes a new instance of the <see cref="LoggerProviderBuilderBase"/> class.
|
||||
/// </summary>
|
||||
public LoggerProviderServiceCollectionBuilder()
|
||||
public LoggerProviderBuilderBase()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
|
|
@ -46,14 +43,12 @@ internal sealed class LoggerProviderServiceCollectionBuilder : LoggerProviderBui
|
|||
.TryAddSingleton<LoggerProvider>(
|
||||
sp => throw new NotSupportedException("Self-contained LoggerProvider cannot be accessed using the application IServiceProvider call Build instead."));
|
||||
|
||||
services.ConfigureOpenTelemetryLoggerProvider((sp, builder) => this.services = null);
|
||||
|
||||
this.services = services;
|
||||
this.innerBuilder = new LoggerProviderServiceCollectionBuilder(services);
|
||||
|
||||
this.allowBuild = true;
|
||||
}
|
||||
|
||||
internal LoggerProviderServiceCollectionBuilder(IServiceCollection services)
|
||||
internal LoggerProviderBuilderBase(IServiceCollection services)
|
||||
{
|
||||
Guard.ThrowIfNull(services);
|
||||
|
||||
|
|
@ -61,9 +56,7 @@ internal sealed class LoggerProviderServiceCollectionBuilder : LoggerProviderBui
|
|||
.AddOpenTelemetryLoggerProviderBuilderServices()
|
||||
.TryAddSingleton<LoggerProvider>(sp => new LoggerProviderSdk(sp, ownsServiceProvider: false));
|
||||
|
||||
services.ConfigureOpenTelemetryLoggerProvider((sp, builder) => this.services = null);
|
||||
|
||||
this.services = services;
|
||||
this.innerBuilder = new LoggerProviderServiceCollectionBuilder(services);
|
||||
|
||||
this.allowBuild = false;
|
||||
}
|
||||
|
|
@ -74,23 +67,26 @@ internal sealed class LoggerProviderServiceCollectionBuilder : LoggerProviderBui
|
|||
/// <inheritdoc />
|
||||
public override LoggerProviderBuilder AddInstrumentation<TInstrumentation>(Func<TInstrumentation> instrumentationFactory)
|
||||
{
|
||||
Guard.ThrowIfNull(instrumentationFactory);
|
||||
|
||||
this.ConfigureBuilderInternal((sp, builder) =>
|
||||
{
|
||||
builder.AddInstrumentation(instrumentationFactory);
|
||||
});
|
||||
this.innerBuilder.AddInstrumentation(instrumentationFactory);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
LoggerProviderBuilder ILoggerProviderBuilder.ConfigureServices(Action<IServiceCollection> configure)
|
||||
=> this.ConfigureServicesInternal(configure);
|
||||
{
|
||||
this.innerBuilder.ConfigureServices(configure);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
LoggerProviderBuilder IDeferredLoggerProviderBuilder.Configure(Action<IServiceProvider, LoggerProviderBuilder> configure)
|
||||
=> this.ConfigureBuilderInternal(configure);
|
||||
{
|
||||
this.innerBuilder.ConfigureBuilder(configure);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
internal LoggerProvider Build()
|
||||
{
|
||||
|
|
@ -99,10 +95,10 @@ internal sealed class LoggerProviderServiceCollectionBuilder : LoggerProviderBui
|
|||
throw new NotSupportedException("A LoggerProviderBuilder bound to external service cannot be built directly. Access the LoggerProvider using the application IServiceProvider instead.");
|
||||
}
|
||||
|
||||
var services = this.services
|
||||
var services = this.innerBuilder.Services
|
||||
?? throw new NotSupportedException("LoggerProviderBuilder build method cannot be called multiple times.");
|
||||
|
||||
this.services = null;
|
||||
this.innerBuilder.Services = null;
|
||||
|
||||
#if DEBUG
|
||||
bool validateScopes = true;
|
||||
|
|
@ -113,26 +109,4 @@ internal sealed class LoggerProviderServiceCollectionBuilder : LoggerProviderBui
|
|||
|
||||
return new LoggerProviderSdk(serviceProvider, ownsServiceProvider: true);
|
||||
}
|
||||
|
||||
private LoggerProviderBuilder ConfigureBuilderInternal(Action<IServiceProvider, LoggerProviderBuilder> configure)
|
||||
{
|
||||
var services = this.services
|
||||
?? throw new NotSupportedException("Builder cannot be configured during LoggerProvider construction.");
|
||||
|
||||
services.ConfigureOpenTelemetryLoggerProvider(configure);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private LoggerProviderBuilder ConfigureServicesInternal(Action<IServiceCollection> configure)
|
||||
{
|
||||
Guard.ThrowIfNull(configure);
|
||||
|
||||
var services = this.services
|
||||
?? throw new NotSupportedException("Services cannot be configured during LoggerProvider construction.");
|
||||
|
||||
configure(services);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -151,9 +151,9 @@ internal static class LoggerProviderBuilderExtensions
|
|||
/// <returns><see cref="LoggerProvider"/>.</returns>
|
||||
public static LoggerProvider Build(this LoggerProviderBuilder loggerProviderBuilder)
|
||||
{
|
||||
if (loggerProviderBuilder is LoggerProviderServiceCollectionBuilder loggerProviderServiceCollectionBuilder)
|
||||
if (loggerProviderBuilder is LoggerProviderBuilderBase loggerProviderBuilderBase)
|
||||
{
|
||||
return loggerProviderServiceCollectionBuilder.Build();
|
||||
return loggerProviderBuilderBase.Build();
|
||||
}
|
||||
|
||||
return new LoggerProvider();
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public static class OpenTelemetryLoggingExtensions
|
|||
// Note: This will bind logger options element (eg "Logging:OpenTelemetry") to OpenTelemetryLoggerOptions
|
||||
LoggerProviderOptions.RegisterProviderOptions<OpenTelemetryLoggerOptions, OpenTelemetryLoggerProvider>(builder.Services);
|
||||
|
||||
new LoggerProviderServiceCollectionBuilder(builder.Services).ConfigureBuilder(
|
||||
new LoggerProviderBuilderBase(builder.Services).ConfigureBuilder(
|
||||
(sp, logging) =>
|
||||
{
|
||||
var options = sp.GetRequiredService<IOptionsMonitor<OpenTelemetryLoggerOptions>>().CurrentValue;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ namespace OpenTelemetry
|
|||
/// to build a <see cref="LoggerProvider"/>.</returns>
|
||||
internal static LoggerProviderBuilder CreateLoggerProviderBuilder()
|
||||
{
|
||||
return new LoggerProviderServiceCollectionBuilder();
|
||||
return new LoggerProviderBuilderBase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,25 +100,32 @@ public class ServiceCollectionExtensionsTests
|
|||
[InlineData(3)]
|
||||
public void ConfigureOpenTelemetryLoggerProvider(int numberOfCalls)
|
||||
{
|
||||
var invocations = 0;
|
||||
var beforeServiceProviderInvocations = 0;
|
||||
var afterServiceProviderInvocations = 0;
|
||||
|
||||
var services = new ServiceCollection();
|
||||
|
||||
for (int i = 0; i < numberOfCalls; i++)
|
||||
{
|
||||
services.ConfigureOpenTelemetryLoggerProvider((sp, builder) => invocations++);
|
||||
services.ConfigureOpenTelemetryLoggerProvider(builder => beforeServiceProviderInvocations++);
|
||||
services.ConfigureOpenTelemetryLoggerProvider((sp, builder) => afterServiceProviderInvocations++);
|
||||
}
|
||||
|
||||
using var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
var registrations = serviceProvider.GetServices<IConfigureLoggerProviderBuilder>();
|
||||
|
||||
Assert.Equal(numberOfCalls, beforeServiceProviderInvocations);
|
||||
Assert.Equal(0, afterServiceProviderInvocations);
|
||||
|
||||
foreach (var registration in registrations)
|
||||
{
|
||||
registration.ConfigureBuilder(serviceProvider, null!);
|
||||
}
|
||||
|
||||
Assert.Equal(invocations, registrations.Count());
|
||||
Assert.Equal(numberOfCalls, registrations.Count());
|
||||
Assert.Equal(numberOfCalls, beforeServiceProviderInvocations);
|
||||
Assert.Equal(numberOfCalls, afterServiceProviderInvocations);
|
||||
|
||||
Assert.Equal(numberOfCalls * 2, registrations.Count());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public sealed class LoggerProviderBuilderExtensionsTests
|
|||
{
|
||||
bool innerConfigureBuilderTestExecuted = false;
|
||||
bool innerConfigureOpenTelemetryLoggerProviderTestExecuted = false;
|
||||
bool innerConfigureOpenTelemetryLoggerProviderTestWithServiceProviderExecuted = false;
|
||||
|
||||
using var provider = Sdk.CreateLoggerProviderBuilder()
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -70,7 +71,17 @@ public sealed class LoggerProviderBuilderExtensionsTests
|
|||
if (callNestedConfigure)
|
||||
{
|
||||
services.ConfigureOpenTelemetryLoggerProvider(
|
||||
(sp, builder) => innerConfigureOpenTelemetryLoggerProviderTestExecuted = true);
|
||||
builder =>
|
||||
{
|
||||
innerConfigureOpenTelemetryLoggerProviderTestExecuted = true;
|
||||
builder.AddInstrumentation<CustomInstrumentation>();
|
||||
});
|
||||
services.ConfigureOpenTelemetryLoggerProvider(
|
||||
(sp, builder) =>
|
||||
{
|
||||
innerConfigureOpenTelemetryLoggerProviderTestWithServiceProviderExecuted = true;
|
||||
Assert.Throws<NotSupportedException>(() => builder.AddInstrumentation<CustomInstrumentation>());
|
||||
});
|
||||
}
|
||||
})
|
||||
.ConfigureBuilder((sp, builder) =>
|
||||
|
|
@ -78,10 +89,22 @@ public sealed class LoggerProviderBuilderExtensionsTests
|
|||
innerConfigureBuilderTestExecuted = true;
|
||||
Assert.Throws<NotSupportedException>(() => sp.GetService<LoggerProvider>());
|
||||
})
|
||||
.Build();
|
||||
.Build() as LoggerProviderSdk;
|
||||
|
||||
Assert.NotNull(provider);
|
||||
|
||||
Assert.True(innerConfigureBuilderTestExecuted);
|
||||
Assert.Equal(callNestedConfigure, innerConfigureOpenTelemetryLoggerProviderTestExecuted);
|
||||
Assert.Equal(callNestedConfigure, innerConfigureOpenTelemetryLoggerProviderTestWithServiceProviderExecuted);
|
||||
|
||||
if (callNestedConfigure)
|
||||
{
|
||||
Assert.Single(provider.Instrumentations);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Empty(provider.Instrumentations);
|
||||
}
|
||||
|
||||
Assert.Throws<NotSupportedException>(() => provider.GetServiceProvider()?.GetService<LoggerProvider>());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,29 @@ public sealed class LoggerProviderSdkTests
|
|||
Assert.True(provider.Processor is CompositeProcessor<LogRecord>);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuilderTypeDoesNotChangeTest()
|
||||
{
|
||||
var originalBuilder = Sdk.CreateLoggerProviderBuilder();
|
||||
var currentBuilder = originalBuilder;
|
||||
|
||||
var deferredBuilder = currentBuilder as IDeferredLoggerProviderBuilder;
|
||||
Assert.NotNull(deferredBuilder);
|
||||
|
||||
currentBuilder = deferredBuilder.Configure((sp, innerBuilder) => { });
|
||||
Assert.True(ReferenceEquals(originalBuilder, currentBuilder));
|
||||
|
||||
currentBuilder = currentBuilder.ConfigureServices(s => { });
|
||||
Assert.True(ReferenceEquals(originalBuilder, currentBuilder));
|
||||
|
||||
currentBuilder = currentBuilder.AddInstrumentation(() => new object());
|
||||
Assert.True(ReferenceEquals(originalBuilder, currentBuilder));
|
||||
|
||||
using var provider = currentBuilder.Build();
|
||||
|
||||
Assert.NotNull(provider);
|
||||
}
|
||||
|
||||
private sealed class NoopProcessor : BaseProcessor<LogRecord>
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue