"重新启动" ASP.Net Core中的单例服务

时间:2018-01-31 10:05:39

标签: 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<DataSettings>(Configuration.GetSection("DataSettings"));
services.AddSingleton<IHostedService, DataService>();

DataService.cs:

public DataService(IOptionsSnapshot<DataSettings> data)                   
{
    //_options is used to configure the service
    this._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());
}

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

1 个答案:

答案 0 :(得分:1)

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

  1. 您确定您的服务需要是一个单身人士吗?大多数情况下,像这样的数据访问服务并不是,而是可以变为Scoped(每个Web请求1个实例)。如果你能支持它,这将消除你的问题。

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

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

  4. 我还没有尝试过,但您可以在运行时(启动后)替换(或删除)服务集合中的单例服务。如果您在对配置进行更新时删除了它,则在下次请求更新时将创建一个新的。以下是相关答案,说明如何在启动中执行此操作:https://stackoverflow.com/a/42946802/13729