Skip to content

Commit

Permalink
[SDK] Remove the dependency on M.E.Options 5.0 (#4093)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeBlanch committed Jan 25, 2023
1 parent ff6efe7 commit 61f5351
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 34 deletions.
2 changes: 1 addition & 1 deletion build/Common.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<MicrosoftExtensionsHostingAbstractionsPkgVer>[2.1.0,)</MicrosoftExtensionsHostingAbstractionsPkgVer>
<MicrosoftExtensionsLoggingPkgVer>[3.1.0,)</MicrosoftExtensionsLoggingPkgVer>
<MicrosoftExtensionsLoggingConfigurationPkgVer>$(MicrosoftExtensionsLoggingPkgVer)</MicrosoftExtensionsLoggingConfigurationPkgVer>
<MicrosoftExtensionsOptionsPkgVer>[5.0.0,)</MicrosoftExtensionsOptionsPkgVer>
<MicrosoftExtensionsOptionsPkgVer>[3.1.0,)</MicrosoftExtensionsOptionsPkgVer>
<MicrosoftNETFrameworkReferenceAssembliesPkgVer>[1.0.3,2.0)</MicrosoftNETFrameworkReferenceAssembliesPkgVer>
<MicrosoftSourceLinkGitHubPkgVer>[1.1.1,2.0)</MicrosoftSourceLinkGitHubPkgVer>
<OpenTracingPkgVer>[0.12.1,0.13)</OpenTracingPkgVer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\ActivityHelperExtensions.cs" Link="Includes\ActivityHelperExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\StatusHelper.cs" Link="Includes\StatusHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ConfigurationExtensions.cs" Link="Includes\ConfigurationExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\EnvironmentVariables\*.cs" Link="Includes\EnvironmentVariables\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\OpenTelemetrySdkEventSource.cs" Link="Includes\OpenTelemetrySdkEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\Options\*.cs" Link="Includes\Options\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PooledList.cs" Link="Includes\PooledList.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeerServiceResolver.cs" Link="Includes\PeerServiceResolver.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ResourceSemanticConventions.cs" Link="Includes\ResourceSemanticConventions.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal sealed class SdkLimitOptions
private int? spanLinkAttributeCountLimit;
private bool spanLinkAttributeCountLimitSet;

internal SdkLimitOptions()
public SdkLimitOptions()
: this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\ActivityHelperExtensions.cs" Link="Includes\ActivityHelperExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\StatusHelper.cs" Link="Includes\StatusHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ConfigurationExtensions.cs" Link="Includes\ConfigurationExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\EnvironmentVariables\*.cs" Link="Includes\EnvironmentVariables\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\OpenTelemetrySdkEventSource.cs" Link="Includes\OpenTelemetrySdkEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\Options\*.cs" Link="Includes\Options\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeriodicExportingMetricReaderHelper.cs" Link="Includes\PeriodicExportingMetricReaderHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeerServiceResolver.cs" Link="Includes\PeerServiceResolver.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ResourceSemanticConventions.cs" Link="Includes\ResourceSemanticConventions.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\ActivityHelperExtensions.cs" Link="Includes\ActivityHelperExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\StatusHelper.cs" Link="Includes\StatusHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ConfigurationExtensions.cs" Link="Includes\ConfigurationExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\EnvironmentVariables\*.cs" Link="Includes\EnvironmentVariables\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\OpenTelemetrySdkEventSource.cs" Link="Includes\OpenTelemetrySdkEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\Options\*.cs" Link="Includes\Options\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PooledList.cs" Link="Includes\PooledList.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeerServiceResolver.cs" Link="Includes\PeerServiceResolver.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ResourceSemanticConventions.cs" Link="Includes\ResourceSemanticConventions.cs" />
Expand Down
7 changes: 6 additions & 1 deletion src/OpenTelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public static bool TryGetValue<T>(
public static IServiceCollection RegisterOptionsFactory<T>(
this IServiceCollection services,
Func<IConfiguration, T> optionsFactoryFunc)
where T : class
where T : class, new()
{
Debug.Assert(services != null, "services was null");
Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null");
Expand All @@ -141,7 +141,7 @@ public static IServiceCollection RegisterOptionsFactory<T>(
public static IServiceCollection RegisterOptionsFactory<T>(
this IServiceCollection services,
Func<IServiceProvider, IConfiguration, string, T> optionsFactoryFunc)
where T : class
where T : class, new()
{
Debug.Assert(services != null, "services was null");
Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null");
Expand All @@ -158,29 +158,4 @@ public static IServiceCollection RegisterOptionsFactory<T>(

return services!;
}

private sealed class DelegatingOptionsFactory<T> : OptionsFactory<T>
where T : class
{
private readonly Func<IConfiguration, string, T> optionsFactoryFunc;
private readonly IConfiguration configuration;

public DelegatingOptionsFactory(
Func<IConfiguration, string, T> optionsFactoryFunc,
IConfiguration configuration,
IEnumerable<IConfigureOptions<T>> setups,
IEnumerable<IPostConfigureOptions<T>> postConfigures,
IEnumerable<IValidateOptions<T>> 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);
}
}
114 changes: 114 additions & 0 deletions src/OpenTelemetry/Internal/Options/DelegatingOptionsFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// <auto-generated /> (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
{
/// <summary>
/// Implementation of <see cref="IOptionsFactory{TOptions}"/>.
/// </summary>
/// <typeparam name="TOptions">The type of options being requested.</typeparam>
internal sealed class DelegatingOptionsFactory<TOptions> :
IOptionsFactory<TOptions>
where TOptions : class, new()
{
private readonly Func<IConfiguration, string, TOptions> optionsFactoryFunc;
private readonly IConfiguration configuration;
private readonly IConfigureOptions<TOptions>[] _setups;
private readonly IPostConfigureOptions<TOptions>[] _postConfigures;
private readonly IValidateOptions<TOptions>[] _validations;

/// <summary>
/// Initializes a new instance with the specified options configurations.
/// </summary>
/// <param name="setups">The configuration actions to run.</param>
/// <param name="postConfigures">The initialization actions to run.</param>
/// <param name="validations">The validations to run.</param>
public DelegatingOptionsFactory(
Func<IConfiguration, string, TOptions> optionsFactoryFunc,
IConfiguration configuration,
IEnumerable<IConfigureOptions<TOptions>> setups,
IEnumerable<IPostConfigureOptions<TOptions>> postConfigures,
IEnumerable<IValidateOptions<TOptions>> 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<TOptions>[] ?? new List<IConfigureOptions<TOptions>>(setups).ToArray();
_postConfigures = postConfigures as IPostConfigureOptions<TOptions>[] ?? new List<IPostConfigureOptions<TOptions>>(postConfigures).ToArray();
_validations = validations as IValidateOptions<TOptions>[] ?? new List<IValidateOptions<TOptions>>(validations).ToArray();
}

/// <summary>
/// Returns a configured <typeparamref name="TOptions"/> instance with the given <paramref name="name"/>.
/// </summary>
/// <param name="name">The name of the <typeparamref name="TOptions"/> instance to create.</param>
/// <returns>The created <typeparamref name="TOptions"/> instance with the given <paramref name="name"/>.</returns>
/// <exception cref="OptionsValidationException">One or more <see cref="IValidateOptions{TOptions}"/> return failed <see cref="ValidateOptionsResult"/> when validating the <typeparamref name="TOptions"/> instance been created.</exception>
/// <exception cref="MissingMethodException">The <typeparamref name="TOptions"/> does not have a public parameterless constructor or <typeparamref name="TOptions"/> is <see langword="abstract"/>.</exception>
public TOptions Create(string name)
{
TOptions options = this.optionsFactoryFunc(this.configuration, name);
foreach (IConfigureOptions<TOptions> setup in _setups)
{
if (setup is IConfigureNamedOptions<TOptions> namedSetup)
{
namedSetup.Configure(name, options);
}
else if (name == Options.DefaultName)
{
setup.Configure(options);
}
}
foreach (IPostConfigureOptions<TOptions> post in _postConfigures)
{
post.PostConfigure(name, options);
}

if (_validations.Length > 0)
{
var failures = new List<string>();
foreach (IValidateOptions<TOptions> 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;
}
}
}
1 change: 0 additions & 1 deletion src/OpenTelemetry/OpenTelemetry.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
<ItemGroup>
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="$(SystemReflectionEmitLightweightPkgVer)" Condition="'$(TargetFramework)' != 'net6.0'" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="$(MicrosoftExtensionsLoggingConfigurationPkgVer)" />
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPkgVer)" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit 61f5351

Please sign in to comment.