Skip to content

Commit 2d0cd1d

Browse files
committed
add support for configuring with custom MuninNodeOptions types
1 parent 485b1a1 commit 2d0cd1d

File tree

4 files changed

+97
-14
lines changed

4 files changed

+97
-14
lines changed

src/Smdn.Net.MuninNode/Smdn.Net.MuninNode.DependencyInjection/IMuninServiceBuilderExtensions.cs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public static class IMuninServiceBuilderExtensions {
1111
/// <summary>
1212
/// Adds a <c>Munin-Node</c> to the <see cref="IMuninServiceBuilder"/> with default configurations.
1313
/// </summary>
14-
/// <param name="builder">An <see cref="IMuninNodeBuilder"/> to build the <c>Munin-Node</c> to be added.</param>
14+
/// <param name="builder">
15+
/// An <see cref="IMuninServiceBuilder"/> that the built <c>Munin-Node</c> will be added to.
16+
/// </param>
1517
/// <returns>The current <see cref="IMuninNodeBuilder"/> so that additional calls can be chained.</returns>
1618
public static IMuninNodeBuilder AddNode(
1719
this IMuninServiceBuilder builder
@@ -25,7 +27,7 @@ this IMuninServiceBuilder builder
2527
/// Adds a <c>Munin-Node</c> to the <see cref="IMuninServiceBuilder"/> with specified configurations.
2628
/// </summary>
2729
/// <param name="builder">
28-
/// An <see cref="IMuninNodeBuilder"/> to build the <c>Munin-Node</c> to be added.
30+
/// An <see cref="IMuninServiceBuilder"/> that the built <c>Munin-Node</c> will be added to.
2931
/// </param>
3032
/// <param name="configure">
3133
/// An <see cref="Action{MuninNodeOptions}"/> to setup <see cref="MuninNodeOptions"/> to
@@ -36,29 +38,48 @@ public static IMuninNodeBuilder AddNode(
3638
this IMuninServiceBuilder builder,
3739
Action<MuninNodeOptions> configure
3840
)
41+
=> AddNode<MuninNodeOptions>(
42+
builder: builder ?? throw new ArgumentNullException(nameof(builder)),
43+
configure: configure ?? throw new ArgumentNullException(nameof(configure))
44+
);
45+
46+
/// <summary>
47+
/// Adds a <c>Munin-Node</c> to the <see cref="IMuninServiceBuilder"/> with specified configurations.
48+
/// </summary>
49+
/// <typeparam name="TMuninNodeOptions">
50+
/// The extended type of <see cref="MuninNodeOptions"/> to configure the <c>Munin-Node</c>.
51+
/// </typeparam>
52+
/// <param name="builder">
53+
/// An <see cref="IMuninServiceBuilder"/> that the built <c>Munin-Node</c> will be added to.
54+
/// </param>
55+
/// <param name="configure">
56+
/// An <see cref="Action{TMuninNodeOptions}"/> to setup <typeparamref name="TMuninNodeOptions"/> to
57+
/// configure the <c>Munin-Node</c> to be built.
58+
/// </param>
59+
/// <returns>The current <see cref="IMuninNodeBuilder"/> so that additional calls can be chained.</returns>
60+
public static IMuninNodeBuilder AddNode<TMuninNodeOptions>(
61+
this IMuninServiceBuilder builder,
62+
Action<TMuninNodeOptions> configure
63+
)
64+
where TMuninNodeOptions : MuninNodeOptions, new()
3965
{
4066
if (builder is null)
4167
throw new ArgumentNullException(nameof(builder));
4268
if (configure is null)
4369
throw new ArgumentNullException(nameof(configure));
4470

45-
var options = new MuninNodeOptions();
71+
var configuredOptions = new TMuninNodeOptions();
4672

47-
configure(options);
73+
configure(configuredOptions);
4874

4975
var nodeBuilder = new MuninNodeBuilder(
5076
serviceBuilder: builder,
51-
serviceKey: options.HostName // use configured hostname as a service key and option name
77+
serviceKey: configuredOptions.HostName // use configured hostname as a service key and option name
5278
);
5379

54-
_ = builder.Services.Configure<MuninNodeOptions>(
80+
_ = builder.Services.Configure<TMuninNodeOptions>(
5581
name: nodeBuilder.ServiceKey, // configure MuninNodeOptions for this builder
56-
opts => {
57-
opts.Address = options.Address;
58-
opts.Port = options.Port;
59-
opts.HostName = options.HostName;
60-
opts.AccessRule = options.AccessRule;
61-
}
82+
options => options.Configure(configuredOptions)
6283
);
6384

6485
builder.Services.Add(

src/Smdn.Net.MuninNode/Smdn.Net.MuninNode.DependencyInjection/MuninNodeBuilder.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public IMuninNode Build(IServiceProvider serviceProvider)
7373
throw new ArgumentNullException(nameof(serviceProvider));
7474

7575
return new DefaultMuninNode(
76-
options: serviceProvider.GetRequiredService<IOptionsMonitor<MuninNodeOptions>>().Get(name: ServiceKey),
76+
options: GetConfiguredOptions<MuninNodeOptions>(serviceProvider),
7777
pluginProvider: buildPluginProvider is null
7878
? new PluginProvider(
7979
plugins: pluginFactories.Select(factory => factory(serviceProvider)).ToList(),
@@ -98,4 +98,15 @@ public PluginProvider(
9898
SessionCallback = sessionCallback;
9999
}
100100
}
101+
102+
protected TMuninNodeOptions GetConfiguredOptions<TMuninNodeOptions>(IServiceProvider serviceProvider)
103+
where TMuninNodeOptions : MuninNodeOptions
104+
{
105+
if (serviceProvider is null)
106+
throw new ArgumentNullException(nameof(serviceProvider));
107+
108+
return serviceProvider
109+
.GetRequiredService<IOptionsMonitor<TMuninNodeOptions>>()
110+
.Get(name: ServiceKey);
111+
}
101112
}

src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/MuninNodeOptions.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Smdn.Net.MuninNode;
1414
/// Options to configure the <c>Munin-Node</c>.
1515
/// </summary>
1616
/// <see cref="DependencyInjection.IMuninServiceBuilderExtensions.AddNode(DependencyInjection.IMuninServiceBuilder, Action{MuninNodeOptions})"/>
17-
public sealed class MuninNodeOptions {
17+
public class MuninNodeOptions {
1818
private static IPAddress LoopbackAddress => Socket.OSSupportsIPv6 ? IPAddress.IPv6Loopback : IPAddress.Loopback;
1919
private static IPAddress AnyAddress => Socket.OSSupportsIPv6 ? IPAddress.IPv6Any : IPAddress.Any;
2020

@@ -124,6 +124,17 @@ public MuninNodeOptions Clone()
124124
=> (MuninNodeOptions)MemberwiseClone();
125125
#endif
126126

127+
protected internal virtual void Configure(MuninNodeOptions baseOptions)
128+
{
129+
if (baseOptions is null)
130+
throw new ArgumentNullException(nameof(baseOptions));
131+
132+
Address = baseOptions.Address;
133+
Port = baseOptions.Port;
134+
HostName = baseOptions.HostName;
135+
AccessRule = baseOptions.AccessRule;
136+
}
137+
127138
/// <summary>
128139
/// Set the value of the <see cref="Address"/> property to use the address of
129140
/// <see cref="IPAddress.Any"/> or <see cref="IPAddress.IPv6Any"/>.

tests/Smdn.Net.MuninNode/Smdn.Net.MuninNode.DependencyInjection/IMuninServiceBuilderExtensions.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55

66
using Microsoft.Extensions.DependencyInjection;
7+
using Microsoft.Extensions.Options;
78

89
using NUnit.Framework;
910

@@ -161,4 +162,43 @@ public void AddNode_Multiple_GetKeyedService(string hostName)
161162
Assert.That(node.HostName, Is.EqualTo(hostName));
162163
Assert.That(node, Is.Not.SameAs(anotherNode));
163164
}
165+
166+
private class CustomMuninNodeOptions : MuninNodeOptions {
167+
public string? ExtraOption { get; set; }
168+
169+
protected override void Configure(MuninNodeOptions baseOptions)
170+
{
171+
base.Configure(baseOptions ?? throw new ArgumentNullException(nameof(baseOptions)));
172+
173+
if (baseOptions is CustomMuninNodeOptions options)
174+
ExtraOption = options.ExtraOption;
175+
}
176+
}
177+
178+
[Test]
179+
public void AddNode_CustomOptionsType()
180+
{
181+
const string HostName = "munin-node.localhost";
182+
const string ExtraOptionValue = "foo";
183+
184+
var services = new ServiceCollection();
185+
186+
services.AddMunin(configure: builder => {
187+
builder.AddNode<CustomMuninNodeOptions>(
188+
configure: options => {
189+
options.HostName = HostName;
190+
options.ExtraOption = ExtraOptionValue;
191+
}
192+
);
193+
});
194+
195+
var serviceProvider = services.BuildServiceProvider();
196+
197+
var options = serviceProvider
198+
.GetRequiredService<IOptionsMonitor<CustomMuninNodeOptions>>()
199+
.Get(name: HostName);
200+
201+
Assert.That(options.HostName, Is.EqualTo(HostName));
202+
Assert.That(options.ExtraOption, Is.EqualTo(ExtraOptionValue));
203+
}
164204
}

0 commit comments

Comments
 (0)