I am creating a Windows service in C# on .NET Core 8. This is my first attempt. The service works, but I now want to remove some hardcoded elements and move the settings into my appsettings.json file.
I've started with just a few settings.
My appsettings.Development.json has the following content:
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"PlannedOutageConn": "Data Source=localhost;Initial Catalog=planned_outage;Persist Security Info=True;User ID=User;Password=password;Trust Server Certificate=True"
},
"Settings": {
"corsOrigin": "http://Server1",
"plannedOutageWebService": "https://localhost:7400/api/triview",
"verboseLogging": true
}
I have a SettingsConfig class:
namespace PlannedOutageWindowsSvc.Models
{
/// <summary>
/// A class representing the various app configurations found in appsettings.{environment}.json
/// </summary>
public class SettingsConfig
{
/// <summary>
/// The origin host e.g. http://localhost or https://Server1
/// </summary>
public string corsOrigin { get; set; } = "";
/// <summary>
/// Api endpoint for Planned Outage Web Service
/// </summary>
public string plannedOutageWebService { get; set; } = "";
/// <summary>
/// Dictates if verbose logging is on or off (boolean)
/// </summary>
public bool verboseLogging { get; set; }
}
}
In my program.cs, I have the following:
using App.WindowsService;
using Microsoft.EntityFrameworkCore;
using PlannedOutageWindowsSvc.Models;
using NLog;
using NLog.Web;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddWindowsService(options =>
{
options.ServiceName = "PlannedOutageWinSvc";
});
var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile($"appsettings.json", false, true)
.AddJsonFile($"appsettings.{env}.json", true, true)
.AddEnvironmentVariables()
.Build();
// Early init of NLog to allow startup and exception logging, before host is built
var mlogger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
mlogger.Warn("PlannedOutageWindowsService is being initiated");
try
{
//DB connection/context
builder.Services.AddDbContext<planned_outageContext>(
options => options.UseSqlServer(builder.Configuration.GetConnectionString("PlannedOutageConn")));
builder.Services.Configure<SettingsConfig>(config.GetSection("Settings"));
builder.Services.AddHostedService<WindowsBackgroundService>();
builder.Services.AddSingleton<PlannedOutageService>();
IHost host = builder.Build();
host.Run();
}
catch (Exception ex)
{
// NLog: catch setup errors
mlogger.Error(ex, "PlannedOutageWindowsService stopped because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
I now want to access my settings from appSettings.{env}.json within my PlannedOutageService.cs singleton class:
using PlannedOutageWindowsSvc.Models;
using System.Text.Json;
namespace App.WindowsService
{
public class PlannedOutageService()
{
private SettingsConfig svcSettings;
public PlannedOutageService(SettingsConfig? appSettings) //ERROR CS8863
{
svcSettings = appSettings;
}
public static async Task ProcessTriViewMessages()
{
//THIS IS WHERE I WANT TO ACCESS THE SETTINGS VALUES
string triviewUrl = svcSetting.plannedOutagesWebService; //ERROR CS0120
// ..... other code removed
}
}
}
The above code results in two errors that I cannot resolve:
CS8862 A constructor declared in a type with parameter list must have 'this' constructor initializer.
CS0120 An object reference is required for the non-static field, method, or property 'PlannedOutageService.svcSettings'
How do I access my settings in a singleton? Many thanks