Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,25 @@ public static IHostBuilder UseApplicationMetadata(this IHostBuilder builder, str
.ConfigureAppConfiguration((hostBuilderContext, configurationBuilder) => configurationBuilder.AddApplicationMetadata(hostBuilderContext.HostingEnvironment, sectionName))
.ConfigureServices((hostBuilderContext, serviceCollection) => serviceCollection.AddApplicationMetadata(hostBuilderContext.Configuration.GetSection(sectionName)));
}

/// <summary>
/// Registers a configuration provider for application metadata and binds a model object onto the configuration.
/// </summary>
/// <typeparam name="TBuilder"><see cref="IHostApplicationBuilder"/>.</typeparam>
/// <param name="builder">The host builder.</param>
/// <param name="sectionName">Section name to bind configuration from. Default set to "ambientmetadata:application".</param>
/// <returns>The value of <paramref name="builder"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="sectionName"/> is either <see langword="null"/>, empty, or whitespace.</exception>
public static TBuilder UseApplicationMetadata<TBuilder>(this TBuilder builder, string sectionName = DefaultSectionName)
where TBuilder : IHostApplicationBuilder
{
_ = Throw.IfNull(builder);
_ = Throw.IfNullOrWhitespace(sectionName);

_ = builder.Configuration.AddApplicationMetadata(builder.Environment, sectionName);
_ = builder.Services.AddApplicationMetadata(builder.Configuration.GetSection(sectionName));

return builder;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"Name": "Microsoft.Extensions.AmbientMetadata.Application, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"Name": "Microsoft.Extensions.AmbientMetadata.Application, Version=9.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"Types": [
{
"Type": "class Microsoft.Extensions.AmbientMetadata.ApplicationMetadata",
Expand Down Expand Up @@ -46,6 +46,10 @@
{
"Member": "static Microsoft.Extensions.Hosting.IHostBuilder Microsoft.Extensions.Hosting.ApplicationMetadataHostBuilderExtensions.UseApplicationMetadata(this Microsoft.Extensions.Hosting.IHostBuilder builder, string sectionName = \"ambientmetadata:application\");",
"Stage": "Stable"
},
{
"Member": "static TBuilder Microsoft.Extensions.Hosting.ApplicationMetadataHostBuilderExtensions.UseApplicationMetadata<TBuilder>(this TBuilder builder, string sectionName = \"ambientmetadata:application\");",
"Stage": "Stable"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The services can be registered using any of the following methods:

```csharp
public static IHostBuilder UseApplicationMetadata(this IHostBuilder builder, string sectionName = DefaultSectionName)
public static TBuilder UseApplicationMetadata<TBuilder>(this TBuilder builder, string sectionName = DefaultSectionName) where TBuilder : IHostApplicationBuilder
public static IServiceCollection AddApplicationMetadata(this IServiceCollection services, Action<ApplicationMetadata> configure)
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,28 @@ await RunAsync(
},
sectionName);

[Theory]
[InlineData("ambientmetadata:application")]
[InlineData(null)]
public async Task UseApplicationMetadata_HostApplicationBuilder_CreatesPopulatesAndRegistersOptions(string? sectionName) =>
await RunAsync_HostBuilder(
(options, hostEnvironment) =>
{
options.BuildVersion.Should().Be(_metadata.BuildVersion);
options.DeploymentRing.Should().Be(_metadata.DeploymentRing);
options.ApplicationName.Should().Be(_metadata.ApplicationName);
options.EnvironmentName.Should().Be(hostEnvironment.EnvironmentName);

return Task.CompletedTask;
},
sectionName);

private static async Task RunAsync(Func<ApplicationMetadata, IHostEnvironment, Task> func, string? sectionName)
{
using var host = await FakeHost.CreateBuilder()

// need to set applicationName manually, because
// netfx console test runner cannot get assebly name
// netfx console test runner cannot get assembly name
// to be able to set it automatically
// see https://source.dot.net/#Microsoft.Extensions.Hosting/HostBuilder.cs,240
.ConfigureHostConfiguration("applicationname", _metadata.ApplicationName)
Expand All @@ -60,4 +76,31 @@ await func(host.Services.GetRequiredService<IOptions<ApplicationMetadata>>().Val
host.Services.GetRequiredService<IHostEnvironment>());
await host.StopAsync();
}

private static async Task RunAsync_HostBuilder(Func<ApplicationMetadata, IHostEnvironment, Task> func, string? sectionName)
{
var builder = Host.CreateEmptyApplicationBuilder(new()
{
ApplicationName = _metadata.ApplicationName
});

// need to set applicationName manually, because
// netfx console test runner cannot get assembly name
// to be able to set it automatically
// see https://source.dot.net/#Microsoft.Extensions.Hosting/HostBuilder.cs,240
builder
.UseApplicationMetadata(sectionName ?? "ambientmetadata:application")
.Services.AddApplicationMetadata(metadata =>
{
metadata.BuildVersion = _metadata.BuildVersion;
metadata.DeploymentRing = _metadata.DeploymentRing;
});

using var host = builder.Build();
await host.StartAsync();

await func(host.Services.GetRequiredService<IOptions<ApplicationMetadata>>().Value,
host.Services.GetRequiredService<IHostEnvironment>());
await host.StopAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,20 @@ public void ApplicationMetadataExtensions_GivenAnyNullArgument_Throws()
Assert.Throws<ArgumentNullException>(() => serviceCollection.AddApplicationMetadata((Action<ApplicationMetadata>)null!));
Assert.Throws<ArgumentNullException>(() => serviceCollection.AddApplicationMetadata((IConfigurationSection)null!));
Assert.Throws<ArgumentNullException>(() => ((IHostBuilder)null!).UseApplicationMetadata(_fixture.Create<string>()));
Assert.Throws<ArgumentNullException>(() => ((IHostApplicationBuilder)null!).UseApplicationMetadata(_fixture.Create<string>()));
Assert.Throws<ArgumentNullException>(() => new ConfigurationBuilder().AddApplicationMetadata(null!));
Assert.Throws<ArgumentNullException>(() => ((IConfigurationBuilder)null!).AddApplicationMetadata(null!));
}

[Fact]
public void ApplicationMetadataExtensions_GivenEmptyAction_DoesNotThrow()
{
var serviceCollection = new ServiceCollection();
var config = new ConfigurationBuilder().Build();

Assert.Null(Record.Exception(() => serviceCollection.AddApplicationMetadata(_ => { })));
}

[Theory]
[InlineData(null)]
[InlineData("")]
Expand All @@ -66,6 +76,17 @@ public void UseApplicationMetadata_InvalidSectionName_Throws(string? sectionName
act.Should().Throw<ArgumentException>();
}

[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
[InlineData(" ")]
public void UseApplicationMetadata_HostApplicationBuilder_InvalidSectionName_Throws(string? sectionName)
{
var act = () => Host.CreateEmptyApplicationBuilder(new()).UseApplicationMetadata(sectionName!);
act.Should().Throw<ArgumentException>();
}

[Fact]
public void AddApplicationMetadata_BuildsConfig()
{
Expand Down
Loading