我正在 C# .net core 8 创建一个 Windows 服务。我的第一次尝试。该服务有效,但我现在想删除一些硬编码元素并在我的应用程序设置文件中进行设置。
我开始时只进行了一些设置。 我的 appsetting.Development.json 具有以下内容:
"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
}
我有一个 SettingsConfig 类:
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; }
}
}
在我的program.cs中,我有以下内容:
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();
}
我现在想从 PlannedOutageService.cs 单例中的 appSettings.{env}.json 访问我的设置:
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
}
}
}
上面的代码给了我两个无法解决的错误: CS8862 在带有参数列表的类型中声明的构造函数必须具有“this”构造函数初始值设定项。 CS0120 非静态字段、方法或属性“PlannedOutageService.svcSettings”需要对象引用
如何在单例中访问我的设置。非常感谢
您应该使用选项模式进行设置。你注册了它们,但是为了通过 DI 获取它们,你应该将它们包装到 IOptions 中:
public PlannedOutageService(IOptions<SettingsConfig> appSettings)
{
// access settings via appSettings.Value, check for NULL if necessary
}
您的第二个问题与设置无关。您试图在静态构造函数中分配私有类字段,这是行不通的。它是一个静态构造函数,因此您只能在那里分配静态字段,因为调用此构造函数时不会创建任何实例。