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 @@
-