.NET Core DI 中的异步提供程序 [英] Async provider in .NET Core DI

查看:24
本文介绍了.NET Core DI 中的异步提供程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道在 DI 期间是否可以使用 async/await.

I'm just wondering if it's possible to have async/await during DI.

执行以下操作,DI 无法解析我的服务.

Doing the following, the DI fails to resolve my service.

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,但在解析依赖时没有多大意义,因为:

Although it is theoretically possible to use async/await during object resolution, it doesn't make much sense when resolving dependencies, because:

这意味着所有涉及 I/O 的事情都应该推迟到对象图构建完成之后.

This means that everything that involves I/O should be postponed until after the object graph has been constructed.

因此,与其注入连接的 MyClientMyClient 应该在第一次使用时连接,而不是在创建时连接.

So instead of injecting a connected MyClient, MyClient should connect when it is used for the first time, not when it is created.

由于您的 MyClient 不是一个应用程序组件,而是一个第三方组件,这意味着您无法确保它连接[s]是第一次使用."

Since your MyClient is not an application component but a third-party component, this means that you can't ensure that it "connect[s] when it is used for the first time."

然而,这应该不是问题,因为依赖倒置原则已经教会了我们那个:

This shouldn't be a problem, however, because the Dependency Inversion Principle already teaches us that:

摘要归上层/策略层所有

the abstracts are owned by the upper/policy layers

这意味着应用程序组件不应直接依赖于第三方组件,而应依赖于应用程序本身定义的抽象.作为组合根的一部分,可以编写适配器来实现这些抽象并使应用程序代码适应第三方库.

This means that application components should not depend on third-party components directly, but instead they should depend on abstractions defined by the application itself. As part of the Composition Root, adapters can be written that implement these abstractions and adapt application code to the third-party libraries.

这样做的一个重要优势是您可以控制应用程序组件使用的 API,这是成功的关键,因为它允许将连接问题完全隐藏在抽象之后.

An important advantage of this is that you are in control over the API that your application components use, which is the key to success here, as it allows the connectivity issues to be hidden behind the abstraction completely.

以下是您的应用程序定制抽象的示例:

Here's an example of how your application-tailored abstraction might look like:

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

请注意,此抽象缺少 ConnectAsync 方法;这隐藏在抽象背后.例如,看看以下适配器:

Do note that this abstraction lacks an ConnectAsync method; this is hidden behind the abstraction. Take a look at the following adapter for instance:

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 中,这允许客户端只连接一次,而与 GetData<的顺序无关/code> 和 SendData 方法被调用了多少次.

The adapter hides the connectivity details from the application code. It wraps the creation and connection of MyClient in a Lazy<T>, which allows the client to be connected just once, independently of in which order the GetData and SendData methods are called, and how many times.

这允许您让您的应用程序组件依赖于 IMyAppService 而不是 MyClient 并将 MyClientAdapter 注册为 IMyAppService> 以适当的生活方式.

This allows you to let your application components depend on IMyAppService instead of MyClient and register the MyClientAdapter as IMyAppService with the appropriate lifestyle.

这篇关于.NET Core DI 中的异步提供程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆