Skip to content

Commit e8657b7

Browse files
authored
Add support for HostApplicationBuilder in AmbientMetadata extension (#6867)
1 parent 75116ba commit e8657b7

File tree

5 files changed

+92
-2
lines changed

5 files changed

+92
-2
lines changed

src/Libraries/Microsoft.Extensions.AmbientMetadata.Application/ApplicationMetadataHostBuilderExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,25 @@ public static IHostBuilder UseApplicationMetadata(this IHostBuilder builder, str
3232
.ConfigureAppConfiguration((hostBuilderContext, configurationBuilder) => configurationBuilder.AddApplicationMetadata(hostBuilderContext.HostingEnvironment, sectionName))
3333
.ConfigureServices((hostBuilderContext, serviceCollection) => serviceCollection.AddApplicationMetadata(hostBuilderContext.Configuration.GetSection(sectionName)));
3434
}
35+
36+
/// <summary>
37+
/// Registers a configuration provider for application metadata and binds a model object onto the configuration.
38+
/// </summary>
39+
/// <typeparam name="TBuilder"><see cref="IHostApplicationBuilder"/>.</typeparam>
40+
/// <param name="builder">The host builder.</param>
41+
/// <param name="sectionName">Section name to bind configuration from. Default set to "ambientmetadata:application".</param>
42+
/// <returns>The value of <paramref name="builder"/>.</returns>
43+
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
44+
/// <exception cref="ArgumentException"><paramref name="sectionName"/> is either <see langword="null"/>, empty, or whitespace.</exception>
45+
public static TBuilder UseApplicationMetadata<TBuilder>(this TBuilder builder, string sectionName = DefaultSectionName)
46+
where TBuilder : IHostApplicationBuilder
47+
{
48+
_ = Throw.IfNull(builder);
49+
_ = Throw.IfNullOrWhitespace(sectionName);
50+
51+
_ = builder.Configuration.AddApplicationMetadata(builder.Environment, sectionName);
52+
_ = builder.Services.AddApplicationMetadata(builder.Configuration.GetSection(sectionName));
53+
54+
return builder;
55+
}
3556
}

src/Libraries/Microsoft.Extensions.AmbientMetadata.Application/Microsoft.Extensions.AmbientMetadata.Application.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"Name": "Microsoft.Extensions.AmbientMetadata.Application, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
2+
"Name": "Microsoft.Extensions.AmbientMetadata.Application, Version=9.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
33
"Types": [
44
{
55
"Type": "class Microsoft.Extensions.AmbientMetadata.ApplicationMetadata",
@@ -46,6 +46,10 @@
4646
{
4747
"Member": "static Microsoft.Extensions.Hosting.IHostBuilder Microsoft.Extensions.Hosting.ApplicationMetadataHostBuilderExtensions.UseApplicationMetadata(this Microsoft.Extensions.Hosting.IHostBuilder builder, string sectionName = \"ambientmetadata:application\");",
4848
"Stage": "Stable"
49+
},
50+
{
51+
"Member": "static TBuilder Microsoft.Extensions.Hosting.ApplicationMetadataHostBuilderExtensions.UseApplicationMetadata<TBuilder>(this TBuilder builder, string sectionName = \"ambientmetadata:application\");",
52+
"Stage": "Stable"
4953
}
5054
]
5155
},

src/Libraries/Microsoft.Extensions.AmbientMetadata.Application/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ The services can be registered using any of the following methods:
2626

2727
```csharp
2828
public static IHostBuilder UseApplicationMetadata(this IHostBuilder builder, string sectionName = DefaultSectionName)
29+
public static TBuilder UseApplicationMetadata<TBuilder>(this TBuilder builder, string sectionName = DefaultSectionName) where TBuilder : IHostApplicationBuilder
2930
public static IServiceCollection AddApplicationMetadata(this IServiceCollection services, Action<ApplicationMetadata> configure)
3031
```
3132

test/Libraries/Microsoft.Extensions.AmbientMetadata.Application.Tests/AcceptanceTests.cs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,28 @@ await RunAsync(
3939
},
4040
sectionName);
4141

42+
[Theory]
43+
[InlineData("ambientmetadata:application")]
44+
[InlineData(null)]
45+
public async Task UseApplicationMetadata_HostApplicationBuilder_CreatesPopulatesAndRegistersOptions(string? sectionName) =>
46+
await RunAsync_HostBuilder(
47+
(options, hostEnvironment) =>
48+
{
49+
options.BuildVersion.Should().Be(_metadata.BuildVersion);
50+
options.DeploymentRing.Should().Be(_metadata.DeploymentRing);
51+
options.ApplicationName.Should().Be(_metadata.ApplicationName);
52+
options.EnvironmentName.Should().Be(hostEnvironment.EnvironmentName);
53+
54+
return Task.CompletedTask;
55+
},
56+
sectionName);
57+
4258
private static async Task RunAsync(Func<ApplicationMetadata, IHostEnvironment, Task> func, string? sectionName)
4359
{
4460
using var host = await FakeHost.CreateBuilder()
4561

4662
// need to set applicationName manually, because
47-
// netfx console test runner cannot get assebly name
63+
// netfx console test runner cannot get assembly name
4864
// to be able to set it automatically
4965
// see https://source.dot.net/#Microsoft.Extensions.Hosting/HostBuilder.cs,240
5066
.ConfigureHostConfiguration("applicationname", _metadata.ApplicationName)
@@ -60,4 +76,31 @@ await func(host.Services.GetRequiredService<IOptions<ApplicationMetadata>>().Val
6076
host.Services.GetRequiredService<IHostEnvironment>());
6177
await host.StopAsync();
6278
}
79+
80+
private static async Task RunAsync_HostBuilder(Func<ApplicationMetadata, IHostEnvironment, Task> func, string? sectionName)
81+
{
82+
var builder = Host.CreateEmptyApplicationBuilder(new()
83+
{
84+
ApplicationName = _metadata.ApplicationName
85+
});
86+
87+
// need to set applicationName manually, because
88+
// netfx console test runner cannot get assembly name
89+
// to be able to set it automatically
90+
// see https://source.dot.net/#Microsoft.Extensions.Hosting/HostBuilder.cs,240
91+
builder
92+
.UseApplicationMetadata(sectionName ?? "ambientmetadata:application")
93+
.Services.AddApplicationMetadata(metadata =>
94+
{
95+
metadata.BuildVersion = _metadata.BuildVersion;
96+
metadata.DeploymentRing = _metadata.DeploymentRing;
97+
});
98+
99+
using var host = builder.Build();
100+
await host.StartAsync();
101+
102+
await func(host.Services.GetRequiredService<IOptions<ApplicationMetadata>>().Value,
103+
host.Services.GetRequiredService<IHostEnvironment>());
104+
await host.StopAsync();
105+
}
63106
}

test/Libraries/Microsoft.Extensions.AmbientMetadata.Application.Tests/ApplicationMetadataExtensionsTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,20 @@ public void ApplicationMetadataExtensions_GivenAnyNullArgument_Throws()
4040
Assert.Throws<ArgumentNullException>(() => serviceCollection.AddApplicationMetadata((Action<ApplicationMetadata>)null!));
4141
Assert.Throws<ArgumentNullException>(() => serviceCollection.AddApplicationMetadata((IConfigurationSection)null!));
4242
Assert.Throws<ArgumentNullException>(() => ((IHostBuilder)null!).UseApplicationMetadata(_fixture.Create<string>()));
43+
Assert.Throws<ArgumentNullException>(() => ((IHostApplicationBuilder)null!).UseApplicationMetadata(_fixture.Create<string>()));
4344
Assert.Throws<ArgumentNullException>(() => new ConfigurationBuilder().AddApplicationMetadata(null!));
4445
Assert.Throws<ArgumentNullException>(() => ((IConfigurationBuilder)null!).AddApplicationMetadata(null!));
4546
}
4647

48+
[Fact]
49+
public void ApplicationMetadataExtensions_GivenEmptyAction_DoesNotThrow()
50+
{
51+
var serviceCollection = new ServiceCollection();
52+
var config = new ConfigurationBuilder().Build();
53+
54+
Assert.Null(Record.Exception(() => serviceCollection.AddApplicationMetadata(_ => { })));
55+
}
56+
4757
[Theory]
4858
[InlineData(null)]
4959
[InlineData("")]
@@ -66,6 +76,17 @@ public void UseApplicationMetadata_InvalidSectionName_Throws(string? sectionName
6676
act.Should().Throw<ArgumentException>();
6777
}
6878

79+
[Theory]
80+
[InlineData(null)]
81+
[InlineData("")]
82+
[InlineData(" ")]
83+
[InlineData(" ")]
84+
public void UseApplicationMetadata_HostApplicationBuilder_InvalidSectionName_Throws(string? sectionName)
85+
{
86+
var act = () => Host.CreateEmptyApplicationBuilder(new()).UseApplicationMetadata(sectionName!);
87+
act.Should().Throw<ArgumentException>();
88+
}
89+
6990
[Fact]
7091
public void AddApplicationMetadata_BuildsConfig()
7192
{

0 commit comments

Comments
 (0)