I'm trying to create a Windows Service using NET 6 and documentation found here.
I'd like to use strongly typed configuration pattern, so I modified startup code this way:
using IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
options.ServiceName = "My Service";
})
.ConfigureAppConfiguration((hostingContext, configuration) =>
{
configuration.Sources.Clear();
IHostEnvironment env = hostingContext.HostingEnvironment;
configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
})
.ConfigureServices((hostingContext, services) =>
{
services.AddSingleton<MyService>();
services.Configure<AppSettings>(hostingContext.Configuration.GetSection("AppSettings"));
services.AddHostedService<WindowsBackgroundService>();
})
.Build();
await host.RunAsync();
Then in MyService.cs:
private AppSettings _appSettings;
public MyClass(AppSettings appSettings)
{
_appSettings = appSettings;
}
This gives me the following exception:
System.InvalidOperationException: 'Unable to resolve service for type 'StatSveglia.Service.AppSettings' while attempting to activate 'StatSveglia.Service.SvegliaService'.'
It seems that this line has no effect:
services.Configure<AppSettings>(hostingContext.Configuration.GetSection("AppSettings"));
How should I change my code to use configuration injection?
A side question: in the example service found in documentation, services.AddHttpClient<JokeService>();
is used to add the service. My service is not an HTTP client, so I preferred .AddSingleton<>
. Is this a good choice?
After further reading I found out that the line:
services.Configure<AppSettings>(hostingContext.Configuration.GetSection("AppSettings"));
registers for dependency injection the class IOptions<AppSettings>
and not AppSettings
itself.
The correct use is therfore:
private IOptions<AppSettings> _appSettings;
public MyClass(IOptions<AppSettings> appSettings)
{
_appSettings = appSettings;
}
private void SomeMethod()
{
var mySetting = _appSettings.Value.MySetting
}