簡體   English   中英

.NET Core DI 中的異步提供程序

[英]Async provider in .NET Core DI

我只是想知道在 DI 期間是否可以進行async/await

執行以下操作,DI 無法解決我的服務。

services.AddScoped(async provider => 
{
  var client = new MyClient();
  await client.ConnectAsync();
  return client;
});

以下工作非常好。

services.AddScoped(provider => 
{
  var client = new MyClient();
  client.ConnectAsync().Wait();
  return client;
});

雖然理論上可以在對象解析過程中使用 async/await,但在解析依賴關系時並沒有多大意義,因為:

這意味着所有涉及 I/O 的事情都應該推遲到構建對象圖之后。

因此,與其注入連接的MyClientMyClient應該在第一次使用時進行連接,而不是在創建時進行連接。

由於您的MyClient不是應用程序組件而是第三方組件,這意味着您無法確保它“在第一次使用時連接[s]”。

然而,這應該不是問題,因為依賴倒置原則已經告訴我們:

摘要歸上層/策略層所有

這意味着應用程序組件不應直接依賴於第三方組件,而應依賴於應用程序本身定義的抽象。 作為Composition Root 的一部分,可以編寫適配器來實現這些抽象並使應用程序代碼適應第三方庫。

這樣做的一個重要優勢是您可以控制應用程序組件使用的 API,這是成功的關鍵,因為它允許將連接問題完全隱藏在抽象背后。

下面是一個示例,說明您的應用程序定制的抽象可能是什么樣子:

public interface IMyAppService
{
    Task<Data> GetData();
    Task SendData(Data data);
}

請注意,此抽象缺少ConnectAsync方法; 這隱藏在抽象背后。 例如,看看以下適配器:

public sealed class MyClientAdapter : IMyAppService, IDisposable
{
    private readonly Lazy<Task<MyClient>> connectedClient;

    public MyClientAdapter()
    {
        this.connectedClient = new Lazy<Task<MyClient>>(async () =>
        {
            var client = new MyClient();
            await client.ConnectAsync();
            return client;
        });
    }

    public async Task<Data> GetData()
    {
        var client = await this.connectedClient.Value;
        return await client.GetData();
    }

    public async Task SendData(Data data)
    {
        var client = await this.connectedClient.Value;
        await client.SendData(data);
    }

    public void Dispose()
    {
        if (this.connectedClient.IsValueCreated)
        {
            this.connectedClient.Value.Dispose();
        }
    }
}

適配器對應用程序代碼隱藏了連接細節。 它將MyClient的創建和連接包裝在一個Lazy<T> ,這允許客戶端只連接一次,與調用GetDataSendData方法的順序以及調用次數無關。

這可以讓你讓你的應用程序組件取決於IMyAppService而不是MyClient並注冊MyClientAdapter作為IMyAppService與適當的生活方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM