diff --git a/build/Common.props b/build/Common.props index 1c52c393218..d47bf985f5e 100644 --- a/build/Common.props +++ b/build/Common.props @@ -40,7 +40,7 @@ [2.1.0,) [3.1.0,) $(MicrosoftExtensionsLoggingPkgVer) - [5.0.0,) + [3.1.0,) [1.0.3,2.0) [1.1.1,2.0) [0.12.1,0.13) diff --git a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj index 1323e95a51a..8744f50528a 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj +++ b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj @@ -22,9 +22,9 @@ - + diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/SdkLimitOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/SdkLimitOptions.cs index 95102517733..28503c1bdad 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/SdkLimitOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/SdkLimitOptions.cs @@ -31,7 +31,7 @@ internal sealed class SdkLimitOptions private int? spanLinkAttributeCountLimit; private bool spanLinkAttributeCountLimitSet; - internal SdkLimitOptions() + public SdkLimitOptions() : this(new ConfigurationBuilder().AddEnvironmentVariables().Build()) { } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj index 3b7a52aa896..4c152e42d23 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj @@ -37,9 +37,9 @@ - + diff --git a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj index a9eb8158e6a..f5d9deea5a7 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj +++ b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj @@ -17,9 +17,9 @@ - + diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 73e50fafa03..d6cd869acda 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,9 +2,14 @@ ## Unreleased -* Removed dependency on Microsoft.Extensions.Configuration.EnvironmentVariables +* Removed the dependency on + Microsoft.Extensions.Configuration.EnvironmentVariables ([#4092](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4092)) +* Removed the explicit reference to Microsoft.Extensions.Options version 5.0 and + reverted back to the transitive reference of version 3.1 + ([#4093](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4093)) + ## 1.4.0-rc.2 Released 2023-Jan-09 diff --git a/src/OpenTelemetry/Internal/ConfigurationExtensions.cs b/src/OpenTelemetry/Internal/Options/ConfigurationExtensions.cs similarity index 81% rename from src/OpenTelemetry/Internal/ConfigurationExtensions.cs rename to src/OpenTelemetry/Internal/Options/ConfigurationExtensions.cs index 08d95f80e7f..dc0abc051a4 100644 --- a/src/OpenTelemetry/Internal/ConfigurationExtensions.cs +++ b/src/OpenTelemetry/Internal/Options/ConfigurationExtensions.cs @@ -120,7 +120,7 @@ public static bool TryGetValue( public static IServiceCollection RegisterOptionsFactory( this IServiceCollection services, Func optionsFactoryFunc) - where T : class + where T : class, new() { Debug.Assert(services != null, "services was null"); Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); @@ -141,7 +141,7 @@ public static IServiceCollection RegisterOptionsFactory( public static IServiceCollection RegisterOptionsFactory( this IServiceCollection services, Func optionsFactoryFunc) - where T : class + where T : class, new() { Debug.Assert(services != null, "services was null"); Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); @@ -158,29 +158,4 @@ public static IServiceCollection RegisterOptionsFactory( return services!; } - - private sealed class DelegatingOptionsFactory : OptionsFactory - where T : class - { - private readonly Func optionsFactoryFunc; - private readonly IConfiguration configuration; - - public DelegatingOptionsFactory( - Func optionsFactoryFunc, - IConfiguration configuration, - IEnumerable> setups, - IEnumerable> postConfigures, - IEnumerable> validations) - : base(setups, postConfigures, validations) - { - Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); - Debug.Assert(configuration != null, "configuration was null"); - - this.optionsFactoryFunc = optionsFactoryFunc!; - this.configuration = configuration!; - } - - protected override T CreateInstance(string name) - => this.optionsFactoryFunc(this.configuration, name); - } } diff --git a/src/OpenTelemetry/Internal/Options/DelegatingOptionsFactory.cs b/src/OpenTelemetry/Internal/Options/DelegatingOptionsFactory.cs new file mode 100644 index 00000000000..59fdd713434 --- /dev/null +++ b/src/OpenTelemetry/Internal/Options/DelegatingOptionsFactory.cs @@ -0,0 +1,114 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/* + Note: This class was copied from + https://github.com/dotnet/runtime/blob/e13e7388dedc6672381e61592c2e74385fe781a5/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs + and then modified to have delegate features needed by the SDK. In the future if + we take a dependency on Microsoft.Extensions.Options v5.0.0 (or greater), much + of this can be removed in favor of the "CreateInstance" API added in 5: + https://learn.microsoft.com/dotnet/api/microsoft.extensions.options.optionsfactory-1.createinstance?view=dotnet-plat-ext-5.0. + See https://github.com/open-telemetry/opentelemetry-dotnet/pull/4093 for an + example of how that works. +*/ + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Options +{ + /// + /// Implementation of . + /// + /// The type of options being requested. + internal sealed class DelegatingOptionsFactory : + IOptionsFactory + where TOptions : class, new() + { + private readonly Func optionsFactoryFunc; + private readonly IConfiguration configuration; + private readonly IConfigureOptions[] _setups; + private readonly IPostConfigureOptions[] _postConfigures; + private readonly IValidateOptions[] _validations; + + /// + /// Initializes a new instance with the specified options configurations. + /// + /// The configuration actions to run. + /// The initialization actions to run. + /// The validations to run. + public DelegatingOptionsFactory( + Func optionsFactoryFunc, + IConfiguration configuration, + IEnumerable> setups, + IEnumerable> postConfigures, + IEnumerable> validations) + { + // The default DI container uses arrays under the covers. Take advantage of this knowledge + // by checking for an array and enumerate over that, so we don't need to allocate an enumerator. + // When it isn't already an array, convert it to one, but don't use System.Linq to avoid pulling Linq in to + // small trimmed applications. + + Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); + Debug.Assert(configuration != null, "configuration was null"); + + this.optionsFactoryFunc = optionsFactoryFunc!; + this.configuration = configuration!; + _setups = setups as IConfigureOptions[] ?? new List>(setups).ToArray(); + _postConfigures = postConfigures as IPostConfigureOptions[] ?? new List>(postConfigures).ToArray(); + _validations = validations as IValidateOptions[] ?? new List>(validations).ToArray(); + } + + /// + /// Returns a configured instance with the given . + /// + /// The name of the instance to create. + /// The created instance with the given . + /// One or more return failed when validating the instance been created. + /// The does not have a public parameterless constructor or is . + public TOptions Create(string name) + { + TOptions options = this.optionsFactoryFunc(this.configuration, name); + foreach (IConfigureOptions setup in _setups) + { + if (setup is IConfigureNamedOptions namedSetup) + { + namedSetup.Configure(name, options); + } + else if (name == Options.DefaultName) + { + setup.Configure(options); + } + } + foreach (IPostConfigureOptions post in _postConfigures) + { + post.PostConfigure(name, options); + } + + if (_validations.Length > 0) + { + var failures = new List(); + foreach (IValidateOptions validate in _validations) + { + ValidateOptionsResult result = validate.Validate(name, options); + if (result is not null && result.Failed) + { + failures.AddRange(result.Failures); + } + } + if (failures.Count > 0) + { + throw new OptionsValidationException(name, typeof(TOptions), failures); + } + } + + return options; + } + } +} diff --git a/src/OpenTelemetry/OpenTelemetry.csproj b/src/OpenTelemetry/OpenTelemetry.csproj index ddc2af154fc..3527d6a3071 100644 --- a/src/OpenTelemetry/OpenTelemetry.csproj +++ b/src/OpenTelemetry/OpenTelemetry.csproj @@ -21,7 +21,6 @@ -