IWebHostBuilder.ConfigureServices 的异步替代方案

问题描述 投票:0回答:1

在 ASP.NET Core 中,某些依赖项需要异步创建。例如,Playwright 可以这样初始化:

public static async Task Main(string[] args) {
  var builder = WebApplication.CreateBuilder(args);
  // ...
  var playwright = await Playwright.CreateAsync();
  var browser = await playwright.Chromium.LaunchAsync();
  var browserContext = await browser.NewContextAsync();
  services.AddSingleton(playwright);
  services.AddSingleton(browser);
  services.AddSingleton(browserContext);
  // ...
  await builder.Build().RunAsync();
}

这是可能的,因为

async Task Main()

但是当在单独的程序集或可重用库中执行时,通常使用以下模式:

builder.AddFoo();

其内部执行此操作:

webHostBuilder.ConfigureServices((context, services) => /* ... */);

...这不是异步的。

是否有异步方式在单独的库中注册服务?

c# asp.net-core asynchronous async-await asp.net-core-7.0
1个回答
0
投票

为需要异步创建的服务注册一个工厂,然后在依赖类中需要时调用该工厂实例的

Create
方法。在创建单例的情况下,将工厂类注册为单例,然后在工厂内跟踪它创建的单例实例,并为所有对
Task<T>
的调用返回结果
Create
。简单的例子:

public PlaywriteFactory
{
    public Lazy<Task<Playwrite>> _playwriteTask;

    public PlaywriteFactory( ...depenencies... )
    {
        _playwriteTask = new Lazy<Task<Playwrite>>( () =>
        {
            ... code that returns Task<Playwrite> ...
        } );
    }

    public Task<Playwrite> CreateAsync()
    {
        return _playwriteTask.Value;
    }
}

/////
services.AddSingleton<PlaywriteFactory>();

///// usage ///
public class SomeClass
{
    private Task<Playwrite> _playwriteTask;

    public SomeClass( PlaywriteFactory factory )
    {
        _playwriteTask = factory.CreateAsync();
    }

    public async Task SomeMethod()
    {
        var playwrite = await _playwriteTask;

        ...
     }
}
© www.soinside.com 2019 - 2024. All rights reserved.