I wrote an application which main purpose is collecting data by OPC UA protocol. I use IHosting extension method UseWindowsService when builidng host. As this was my first project where I tried dependency injection, I created logging class for writing info to txt files on target system. I also use appsettings.json for application settings:
IHost host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) => {
services.AddSingleton<IOpcLogger, OpcFileLogger>(provider => new OpcFileLogger(@$"{System.AppContext.BaseDirectory}logs"));
services.AddSingleton(hostContext.Configuration.GetSection("OpcSettings").Get<OpcSettings>()!);
services.AddHostedService<OpcUaWorker>();
})
.Build();
It works well, but I wanted to implement default settings file creation for situation in which that file is accidentaly deleted. In my worker class I added lines:
public OpcUaWorker(IOpcLogger opcLogger, OpcSettings opcSettings)
{
_opcLogger = opcLogger;
_opcSettings = opcSettings;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (_opcSettings == null) {
if (!File.Exists(AppSettingsFilePath)) {
JsonSerializerOptions options = new() { WriteIndented = true };
using FileStream fileStream = new(AppSettingsFilePath, FileMode.Create, FileAccess.Write);
await JsonSerializer.SerializeAsync<OpcSettingsWrapper>(fileStream, new OpcSettingsWrapper(new OpcSettings()), options);
}
If I delete appsettings.json before service start, either sc start
or using ServiceManager UI, it fails to start with Service Control Manager Event 7000, The service did not respond to the start or control request in a timely fashion.
.
Singleton object is created once and injected using constructor, so its behavior is predictable in the example described above (after successful start deletion of the file and further check in ExecuteAsync have no sense). How to create it on start?