A configuration provider that reloads when it receives a message containing configuration changes from a RockLib.Messaging.IReceiver
.
Add the messaging provider to an existing configuration builder with the AddRockLibMessagingProvider
extension (in the RockLib.Configuration.MessagingProvider
namespace). Note that the messaging configuration provider does not add any values to the configuration initially.
There are two overloads for the extension method. The first one uses an existing instance of IReceiver
:
IReceiver receiver = new NamedPipeReceiver(name: "example_receiver", pipeName: "example-pipe-name");
ConfigurationBuilder builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddRockLibMessagingProvider(receiver); // Add the messaging provider last
The other overload creates a new instance of IReceiver
by name from the configuration under construction:
{
"RockLib.Messaging": {
"type": "RockLib.Messaging.NamedPipes.NamedPipeReceiver, RockLib.Messaging.NamedPipes",
"value": {
"name": "example_receiver",
"pipeName": "example-pipe-name"
}
}
}
ConfigurationBuilder builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json") // Assume appsettings.json contains the above JSON
.AddRockLibMessagingProvider("example_receiver"); // Add the messaging provider last
Each of these example adds an equivalent messaging provider to the configuration builder. All IConfigurationRoot
objects built by the configuration builder will listen to the same IReceiver
for configuration changes.
This section assumes there is an appsettings.json
file and a configuration built as follows:
{
"AppSettings": {
"Foo": "abc",
"Bar": 123
}
}
IReceiver receiver = new NamedPipeReceiver(name: "example_receiver", pipeName: "example-pipe-name");
ConfigurationBuilder builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddRockLibMessagingProvider(receiver);
IConfigurationRoot configuration = builder.Build();
To make a configuration change, send a message to the receiver with a JSON payload that describes the configuration changes. In this example, we want to change the values of AppSettings:Foo
and AppSettings:Bar
to "xyz"
and 456
respectively. Note that the JSON is flattened into key/value pairs.
string configChange = @"{
""AppSettings:Foo"": ""xyz"",
""AppSettings:Bar"": 456
}";
using (ISender sender = new NamedPipeSender(name: "example_receiver", pipeName: "example-pipe-name"))
{
await sender.SendAsync(configChange);
}
After the message is received, the configuration
object will have the new values for "AppSettings:Foo" and "AppSettings:Bar".
The messaging configuration provider can be protected by passing a instance of the ISettingFilter
instance to the extension methods. For reference, this is the definition of that interface:
public interface ISettingFilter
{
bool ShouldProcessSettingChange(string setting, IReadOnlyDictionary<string, object> receivedMessageHeaders);
}
When a message is received, each setting is passed to the ShouldProcessSettingChange
method along with the Headers
property of the received message. If the method returns true, the setting is changed. Otherwise, the setting is not changed.
RockLib.Configuration.MessagingProvider has three implementations of the ISettingFilter
interface:
BlocklistSettingFilter
- Blocks specified settings, including child settings.
- Has an optional inner filter.
SafelistSettingFilter
- Blocks any settings, including child settings, that are not specified.
- Has an optional inner filter.
NullSettingFilter
- Doesn't block any settings.