Skip to content

Commit bb54c57

Browse files
add dynamic configuration tutorial for .net background service
1 parent c58670d commit bb54c57

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

articles/azure-app-configuration/enable-dynamic-configuration-dotnet-background-service.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,166 @@ You use the [.NET command-line interface (CLI)](/dotnet/core/tools/) to create a
4949
dotnet new worker
5050
```
5151
52+
## Reload data from App Configuration
53+
54+
1. Add references to the `Microsoft.Extensions.Configuration.AzureAppConfiguration` NuGet package by running the following commands:
55+
56+
```dotnetcli
57+
dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration
58+
```
59+
60+
1. Run the following command to restore packages for your project:
61+
62+
```dotnetcli
63+
dotnet restore
64+
```
65+
66+
1. Open *Program.cs* and add the following statements:
67+
68+
```csharp
69+
using Microsoft.Extensions.Configuration;
70+
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
71+
```
72+
73+
1. Connect to App Configuration.
74+
75+
```csharp
76+
builder.Configuration.AddAzureAppConfiguration(options =>
77+
{
78+
options.Connect(Environment.GetEnvironmentVariable("ConnectionString"))
79+
// Load all keys that start with `TestApp:`.
80+
.Select("TestApp:*")
81+
// Configure to reload the key 'TestApp:Settings:Message' if it is modified.
82+
.ConfigureRefresh(refresh =>
83+
{
84+
refresh.Register("TestApp:Settings:Message")
85+
.SetCacheExpiration(TimeSpan.FromSeconds(5));
86+
});
87+
88+
// Register the refresher so that the Worker service can consume it through DI
89+
builder.Services.AddSingleton(options.GetRefresher());
90+
});
91+
92+
builder.Services.AddFeatureManagement();
93+
```
94+
95+
In the `ConfigureRefresh` method, a key within your App Configuration store is registered for change monitoring. The `Register` method has an optional boolean parameter `refreshAll` that can be used to indicate whether all configuration values should be refreshed if the registered key changes. In this example, only the key *TestApp:Settings:Message* will be refreshed. The `SetCacheExpiration` method specifies the minimum time that must elapse before a new request is made to App Configuration to check for any configuration changes. In this example, you override the default expiration time of 30 seconds, specifying a time of 5 seconds instead for demonstration purposes.
96+
97+
1. Open *Worker.cs*. Inject `IConfiguration` and `IConfigurationRefresher` to the `Worker` service and log the configuration data from App Configuration.
98+
99+
```csharp
100+
public class Worker : BackgroundService
101+
{
102+
private readonly ILogger<Worker> _logger;
103+
private static IConfiguration _configuration;
104+
private readonly IConfigurationRefresher _refresher;
105+
106+
public Worker(ILogger<Worker> logger, IConfiguration configuration, IConfigurationRefresher refresher)
107+
{
108+
_logger = logger;
109+
_configuration = configuration;
110+
_refresher = refresher;
111+
}
112+
113+
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
114+
{
115+
while (!stoppingToken.IsCancellationRequested)
116+
{
117+
if (_refresher != null)
118+
{
119+
await _refresher.TryRefreshAsync(stoppingToken);
120+
}
121+
122+
if (_logger.IsEnabled(LogLevel.Information))
123+
{
124+
_logger.LogInformation(_configuration["TestApp:Settings:Message"] ?? "No data.");
125+
}
126+
await Task.Delay(1000, stoppingToken);
127+
}
128+
}
129+
}
130+
```
131+
132+
Calling the `ConfigureRefresh` method alone won't cause the configuration to refresh automatically. You call the `TryRefreshAsync` method from the interface `IConfigurationRefresher` to trigger a refresh. This design is to avoid phantom requests sent to App Configuration even when your application is idle. You can include the `TryRefreshAsync` call where you consider your application active. For example, it can be when you process an incoming message, an order, or an iteration of a complex task. It can also be in a timer if your application is active all the time. In this example, you call `TryRefreshAsync` when you press the Enter key. Note that, even if the call `TryRefreshAsync` fails for any reason, your application will continue to use the cached configuration. Another attempt will be made when the configured cache expiration time has passed and the `TryRefreshAsync` call is triggered by your application activity again. Calling `TryRefreshAsync` is a no-op before the configured cache expiration time elapses, so its performance impact is minimal, even if it's called frequently.
133+
134+
## Build and run the app locally
135+
136+
1. Set an environment variable named **ConnectionString**, and set it to the access key to your App Configuration store. At the command line, run the following command.
137+
138+
### [Windows command prompt](#tab/windowscommandprompt)
139+
140+
To build and run the app locally using the Windows command prompt, run the following command.
141+
142+
```console
143+
setx ConnectionString "connection-string-of-your-app-configuration-store"
144+
```
145+
146+
Restart the command prompt to allow the change to take effect. Print the value of the environment variable to validate that it's set properly.
147+
148+
### [PowerShell](#tab/powershell)
149+
150+
If you use Windows PowerShell, run the following command.
151+
152+
```azurepowershell
153+
$Env:ConnectionString = "connection-string-of-your-app-configuration-store"
154+
```
155+
156+
### [macOS](#tab/unix)
157+
158+
If you use macOS, run the following command.
159+
160+
```console
161+
export ConnectionString='connection-string-of-your-app-configuration-store'
162+
```
163+
164+
### [Linux](#tab/linux)
165+
166+
If you use Linux, run the following command.
167+
168+
```console
169+
export ConnectionString='connection-string-of-your-app-configuration-store'
170+
```
171+
172+
---
173+
174+
1. Run the following command to build the console app.
175+
176+
```dotnetcli
177+
dotnet build
178+
```
179+
180+
1. After the build successfully completes, run the following command to run the app locally.
181+
182+
```dotnetcli
183+
dotnet run
184+
```
185+
186+
1. You should see the following outputs in the console.
187+
188+
![Background service](./media/dotnet-background-service-run.png)
189+
190+
1. In the Azure portal, navigate to the **Configuration explorer** of your App Configuration store, and update the value of the following key.
191+
192+
| Key | Value |
193+
|----------------------------|-----------------------------------------------|
194+
| *TestApp:Settings:Message* | *Data from Azure App Configuration - Updated* |
195+
196+
1. Wait for about 5 seconds. You should see the console outputs changed.
197+
198+
![Background service refresh](./media/dotnet-background-service-refresh.png)
199+
200+
## Clean up resources
201+
202+
[!INCLUDE [azure-app-configuration-cleanup](../../includes/azure-app-configuration-cleanup.md)]
203+
204+
## Next steps
205+
206+
In this tutorial, you enabled your .NET background service to dynamically refresh configuration settings from App Configuration. To learn how to enable dynamic configuration in an ASP.NET Web Application, continue to the next tutorial:
207+
208+
> [!div class="nextstepaction"]
209+
> [Enable dynamic configuration in ASP.NET Web Applications](./enable-dynamic-configuration-aspnet-core.md)
210+
211+
To learn how to use an Azure managed identity to streamline the access to App Configuration, continue to the next tutorial:
212+
213+
> [!div class="nextstepaction"]
214+
> [Managed identity integration](./howto-integrate-azure-managed-service-identity.md)
101 KB
Loading
55.7 KB
Loading

0 commit comments

Comments
 (0)