我在 ASP.Net Core 应用程序中使用 DI 注入(inject)了一些服务。这些服务使用几个可写配置对象,我也使用 DI 注入(inject)这些对象。但是,由于这些服务需要是单例的,配置对象仅在服务启动时传递,因此不会获取对其的任何更改。所以我需要重新启动这些单例或以某种方式将新的 IOptionsSnapshot
传递给它们。
为了进一步说明,这是我的代码:
启动.cs:
//Inject service and config object
services.ConfigureWritable<DataSettings>(Configuration.GetSection("DataSettings"));
services.AddSingleton<IHostedService, DataService>();
数据服务.cs:
public DataService(IOptionsSnapshot<DataSettings> data)
{
//_options is used to configure the service
this._options = data.Value;
}
数据 Controller .cs:
public DataController(IWritableOptions<DataSettings> data)
{
_data = data;
}
[HttpPost("conf/data/new")]
public void InsertData([FromBody] IEnumerable<ModuleSettings> newData)
{
var data = _data.Value.Data.ToList();
data.AddRange(newData.ToList());
_data.Update(d => d.Data = data.ToArray());
}
如您所见,我使用 Startup.cs 中的配置对象设置了我的服务。然后我将配置对象传递给我的服务和用于配置服务的 Controller 。接口(interface) IWritableOptions
派生自 IOptionsSnapshot
,可用于将更改写回到 appsettings.json。这一切都有效,但是,当我更改我的配置对象并更新 appsettings.json 时,更改不会传递到我的服务中。重新启动整个应用程序就太过分了,所以我正在寻找一种方法来重新启动该服务或以某种方式在其中设置配置对象。我无法公开服务的 _options
属性,因为这些服务是动态配置的,因此可能有 2、3 等在后台运行。
最佳答案
一些可能有帮助的想法:
您确定您的服务需要是单例吗?大多数时候,像这样的数据访问服务不会,而是可以将其设置为作用域(每个 Web 请求 1 个实例)。如果您可以支持,这将消除您的问题。
您可以传入 IOptions 或您将创建的某些自定义 OptionsReader 类型,而不是传入 IOptionsSnapshot,这将通过一种方法从配置中主动读取当前值。从您的单例服务调用此方法,您应该能够获取任何给定调用的当前连接详细信息。
修改您的服务以接受其连接详细信息作为其方法签名的一部分。不理想,因为您可能需要将它添加到许多方法中,但它会实现您的目标。
我还没有尝试过,但您可以在运行时(启动后)替换(或删除)服务集合中的单例服务。如果您在任何时候对配置进行更新时将其删除,则在下一次请求时将创建一个新的。这是一个相关的答案,显示了如何从启动中执行此操作:https://stackoverflow.com/a/42946802/13729
关于c# - "Restart"ASP.Net Core 中的单例服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48539424/