Skip to content

Commit 83a0eed

Browse files
committed
Add support for IOptions(Monitor) in http host extension
1 parent 46ed266 commit 83a0eed

4 files changed

Lines changed: 75 additions & 0 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
4+
5+
namespace Dibix.Http.Host
6+
{
7+
internal sealed class OptionsMonitorSubscriberOptions
8+
{
9+
public ICollection<Func<IServiceProvider, IDisposable?>> Subscribers { get; } = new Collection<Func<IServiceProvider, IDisposable?>>();
10+
}
11+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Microsoft.Extensions.Hosting;
7+
using Microsoft.Extensions.Options;
8+
9+
namespace Dibix.Http.Host
10+
{
11+
internal sealed class OptionsMonitorSubscriberService : IHostedService
12+
{
13+
private readonly IOptions<OptionsMonitorSubscriberOptions> _options;
14+
private readonly IServiceProvider _serviceProvider;
15+
private readonly ICollection<IDisposable> _disposables;
16+
17+
public OptionsMonitorSubscriberService(IOptions<OptionsMonitorSubscriberOptions> options, IServiceProvider serviceProvider)
18+
{
19+
_options = options;
20+
_disposables = new Collection<IDisposable>();
21+
_serviceProvider = serviceProvider;
22+
}
23+
24+
public Task StartAsync(CancellationToken cancellationToken)
25+
{
26+
foreach (Func<IServiceProvider, IDisposable?> subscriber in _options.Value.Subscribers)
27+
{
28+
IDisposable? disposable = subscriber(_serviceProvider);
29+
if (disposable != null)
30+
_disposables.Add(disposable);
31+
}
32+
33+
return Task.CompletedTask;
34+
}
35+
36+
public Task StopAsync(CancellationToken cancellationToken)
37+
{
38+
foreach (IDisposable disposable in _disposables)
39+
{
40+
disposable.Dispose();
41+
}
42+
43+
return Task.CompletedTask;
44+
}
45+
}
46+
}

src/Dibix.Http.Host/Registration/HttpHostExtensionRegistrar.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.Extensions.DependencyInjection;
1313
using Microsoft.Extensions.Hosting;
1414
using Microsoft.Extensions.Logging;
15+
using Microsoft.Extensions.Options;
1516

1617
namespace Dibix.Http.Host
1718
{
@@ -61,6 +62,9 @@ IHttpHostExtensionConfigurationBuilder IHttpHostExtensionConfigurationBuilder.En
6162
return this;
6263
}
6364

65+
IHttpHostExtensionConfigurationBuilder IHttpHostExtensionConfigurationBuilder.ConfigureOptions<TOptions>(string sectionName, Action<TOptions, string?>? optionsMonitorSubscriber) where TOptions : class => Configure(Configuration.GetSection(sectionName), optionsMonitorSubscriber);
66+
IHttpHostExtensionConfigurationBuilder IHttpHostExtensionConfigurationBuilder.ConfigureOptions<TOptions>(IConfiguration configuration, Action<TOptions, string?>? optionsMonitorSubscriber) where TOptions : class => Configure(configuration, optionsMonitorSubscriber);
67+
6468
IHttpHostExtensionConfigurationBuilder IHttpHostExtensionConfigurationBuilder.ConfigureJwtBearer(Action<JwtBearerOptions> configure)
6569
{
6670
_services.PostConfigure(JwtBearerDefaults.AuthenticationScheme, configure);
@@ -122,6 +126,18 @@ async Task IHttpHostExtensionRegistrar.Configure(IHost host)
122126
return this;
123127
}
124128

129+
private IHttpHostExtensionConfigurationBuilder Configure<TOptions>(IConfiguration configuration, Action<TOptions, string?>? optionsMonitorSubscriber) where TOptions : class
130+
{
131+
_services.Configure<TOptions>(configuration);
132+
if (optionsMonitorSubscriber != null)
133+
{
134+
Func<IServiceProvider, IDisposable?> subscribeToOptionsMonitor = x => x.GetRequiredService<IOptionsMonitor<TOptions>>().OnChange(optionsMonitorSubscriber);
135+
_services.Configure<OptionsMonitorSubscriberOptions>(x => x.Subscribers.Add(subscribeToOptionsMonitor));
136+
_services.AddHostedService<OptionsMonitorSubscriberService>();
137+
}
138+
return this;
139+
}
140+
125141
private void SubscribeToShutdown(IServiceProvider services)
126142
{
127143
IHostApplicationLifetime hostApplicationLifetime = services.GetRequiredService<IHostApplicationLifetime>();

src/Dibix.Http.Server/Registration/IHttpHostExtensionConfigurationBuilder.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ public interface IHttpHostExtensionConfigurationBuilder
1010
#endif
1111

1212
IHttpHostExtensionConfigurationBuilder EnableRequestIdentityProvider();
13+
IHttpHostExtensionConfigurationBuilder ConfigureOptions<TOptions>(string sectionName, Action<TOptions, string> optionsMonitorSubscriber = null) where TOptions : class;
1314
#if NET
15+
IHttpHostExtensionConfigurationBuilder ConfigureOptions<TOptions>(Microsoft.Extensions.Configuration.IConfiguration configuration, Action<TOptions, string> optionsMonitorSubscriber = null) where TOptions : class;
1416
IHttpHostExtensionConfigurationBuilder ConfigureJwtBearer(Action<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> configure);
1517
IHttpHostExtensionConfigurationBuilder EnableCustomAuthentication<THandler, TOptions>(string schemeName) where THandler : Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions, new();
1618
IHttpHostExtensionConfigurationBuilder EnableCustomAuthentication<THandler, TOptions>(string schemeName, Action<TOptions> configureOptions) where THandler : Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions, new();

0 commit comments

Comments
 (0)