【问题标题】:ASP.NET core call async init on singleton serviceASP.NET 核心在单例服务上调用异步初始化
【发布时间】:2019-05-10 12:02:26
【问题描述】:

我有一个服务,它以一种名为 InitAsync 的方法从文件中异步读取一些内容

public class MyService : IService {
    private readonly IDependency injectedDependency;

    public MyService(IDependency injectedDependency) {
        this.injectedDependency = injectedDependency;
    }

    public async Task InitAsync() {
        // async loading from file.
    }
}

现在这个服务被注入到我的控制器中。

public class MyController : Controller {
    private readonly IService service;

    public MyController(IService service) {
        this.service = service;
    }
}

现在我想要一个 MyService 的单例实例。我想在启动时调用 InitAsync。

public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        ......
        services.AddSingleton<IService, MyService>();
        var serviceProvider = services.BuildServiceProvider();
        // perform async init.
        serviceProvider.GetRequiredService<IService>().InitAsync();
    }
}

正在发生的事情是在启动时,创建了一个 MyService 实例并在其上调用 InitAsync()。然后,当我调用控制器类时,会创建另一个 MyService 实例,然后将其重用于后续调用。

我需要的是只初始化 1 个实例,在启动时对其调用 InitAsync() 并让它也被控制器重用。

【问题讨论】:

标签: c# asp.net-core dependency-injection


【解决方案1】:

正在发生的事情是在启动时,创建了一个 MyService 实例并在其上调用 InitAsync()。然后,当我调用控制器类时,会创建另一个 MyService 实例,然后将其重用于后续调用。

当您调用BuildServiceProvider() 时,您会创建一个单独的IServiceProvider 实例,它会创建自己的IService 单例实例。解析为MyController 提供的IService 时使用的IServiceProvider 与您自己创建的不同,因此IService 本身也不同(并且未初始化)。

我需要的是只初始化 1 个实例,在启动时对其调用 InitAsync() 并让它也被控制器重用。

您可以在Program.Main 中执行此操作,而不是尝试在Startup.ConfigureServices 中解析和初始化IService。这允许做两件事:

  1. 使用IService相同实例进行初始化和以后使用。
  2. awaiting 调用 InitAsync,在您展示的方法中,这目前是一劳永逸的。

以下是Program.Main 的外观示例:

public static async Task Main(string[] args)
{
    var webHost = CreateWebHostBuilder(args).Build();

    await webHost.Services.GetRequiredService<IService>().InitAsync();

    webHost.Run();
    // await webHost.RunAsync();
}

这使用async Main 来启用await,构建IWebHost 并使用它的IServiceProvider 来解析和初始化IService。该代码还显示了如何将awaitRunAsync 一起使用,如果您愿意的话,现在方法是async

【讨论】:

    猜你喜欢
    • 2020-10-12
    • 2018-06-26
    • 1970-01-01
    • 2016-07-23
    • 2013-04-23
    • 2021-01-29
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多