C# &引用;“重新启动”;ASP.Net内核中的单例服务

C# &引用;“重新启动”;ASP.Net内核中的单例服务,c#,service,asp.net-core,asp.net-core-mvc-2.0,C#,Service,Asp.net Core,Asp.net Core Mvc 2.0,我在ASP.Net核心应用程序中使用DI注入了一些服务。这些服务使用两个可写的配置对象,我也使用DI注入这些对象。但是,由于这些服务需要是单例的,因此只有在服务启动时才会传递配置对象,因此不会获取对其所做的任何更改。因此,我需要重新启动这些单例,或者以某种方式将新的IOptionsSnapshot传递给它们 为了进一步澄清,以下是我的代码: Startup.cs: //Inject service and config object services.ConfigureWritable<D

我在ASP.Net核心应用程序中使用DI注入了一些服务。这些服务使用两个可写的配置对象,我也使用DI注入这些对象。但是,由于这些服务需要是单例的,因此只有在服务启动时才会传递配置对象,因此不会获取对其所做的任何更改。因此,我需要重新启动这些单例,或者以某种方式将新的
IOptionsSnapshot
传递给它们

为了进一步澄清,以下是我的代码:

Startup.cs:

//Inject service and config object
services.ConfigureWritable<DataSettings>(Configuration.GetSection("DataSettings"));
services.AddSingleton<IHostedService, DataService>();
//注入服务和配置对象
services.ConfigureWritable(Configuration.GetSection(“数据设置”);
services.AddSingleton();
DataService.cs:

public DataService(IOptionsSnapshot<DataSettings> data)                   
{
    //_options is used to configure the service
    this._options = data.Value;
}
公共数据服务(IOptionsSnapshot数据)
{
//_选项用于配置服务
此参数为.\u options=data.Value;
}
DataController.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());
}
公共数据控制器(IWritableOptions数据)
{
_数据=数据;
}
[HttpPost(“conf/data/new”)]
public void InsertData([FromBody]IEnumerable newData)
{
var data=_data.Value.data.ToList();
data.AddRange(newData.ToList());
_data.Update(d=>d.data=data.ToArray());
}

如您所见,我使用Startup.cs中的config对象设置了我的服务。然后我将config对象传递给我的服务和用于配置服务的控制器。接口
IWritableOptions
源自
IOptionsSnapshot
,可用于写回对appsettings.json的更改。但是,当我对配置对象进行更改并更新appsettings.json时,这些更改不会传递到我的服务中。重新启动整个应用程序会有点过分,所以我正在寻找一种方法来重新启动一个服务,或者以某种方式在其中设置config对象。我无法公开服务的
\u options
属性,因为这些服务是动态配置的,因此可能会有2、3等在后台运行。

一些想法可能会有所帮助:

  • 你确定你的服务必须是单身吗?大多数情况下,像这样的数据访问服务不会,而是可以设置范围(每个web请求一个实例)。如果您能够支持,这将消除您的问题

  • 您可以传入IOptionsSnapshot,而不是传入IOptions或您将创建的一些自定义选项读取器类型,这些选项将通过方法从配置中主动读取当前值。从singleton服务调用此方法,您应该能够获取任何给定调用的当前连接详细信息

  • 修改服务以接受其连接详细信息作为其方法签名的一部分。这并不理想,因为您可能需要将其添加到许多方法中,但它可以实现您的目标

  • 我还没有尝试过,但您可能可以在运行时(启动后)替换(或删除)services集合中的singleton服务。如果您在任何时候对配置进行更新时将其删除,则下次请求时将创建一个新的配置。下面是一个相关的答案,说明了如何在启动中执行此操作:


  • 配置和选项有一个更改通知系统,您应该查看它。