c# - 我们是否应该对 C# 中从 Microsoft.Rest.ServiceClient 派生的客户端使用单例?

标签 c# .net azure autorest

使用从 swagger 规范生成的 Azure .NET SDK(例如与 Azure 资源管理器相关的规范)时,生成的库利用 Microsoft AutoRest 客户端运行时,并且各种“客户端”均继承自“ServiceClient”。

我们一直在使用 DocumentDB Client,并阅读了大量有关在 .NET 中使用 native HttpClient 的问题。 Microsoft 建议对这两个客户端使用单例模式,因为它们的内部工作方式,尽管使用单例模式存在众所周知的问题。在这些情况下,这是必要的。

因此,我们针对这些情况制定了使用和管理单例的策略,因此我们想知道是否应该对从 ServiceClient 派生的 Azure REST 客户端使用相同的策略。如果它使用 HttpClient 那就有意义了。

注意:此问题不是寻求有关单例或客户端的一般开发人员建议的问题,而是针对与 AutoRest 客户端运行时相关的 Microsoft 开发团队的特定问题,该问题基于对其内部工作原理的了解。

最佳答案

我一直在尝试解决同样的问题。我正在使用许多自动休息服务客户端,但必须在每个请求时重新实例化它们以传递特定于用户的客户端凭据。使用 Microsoft.Rest.ClientRuntime 2.3.6,您现在可以使用自己的 HttpClient 实例化 ServiceClient。这允许我将 transient ServiceClient 与单例 HttpClient 一起使用。我只是向生成的自动休息客户端添加了一个新的构造函数。

public partial class MyClient : ServiceClient<IMyClient>, IMyClient
{

    public MyClient(Uri baseUri, ServiceClientCredentials credentials, HttpClient client) : base(client)
    {
        if (baseUri == null)
        {
            throw new ArgumentNullException("baseUri");
        }
        if (credentials == null)
        {
            throw new ArgumentNullException("credentials");
        }

        this.Initialize();
        this.Credentials = credentials;
        Credentials?.InitializeServiceClient(this);
        this.BaseUri = baseUri;

    }
    [...]
}

但是,这会在第一次请求后导致 ObjectDisposeException。这是因为 ServiceClient 会处理 HttpClient,无论您是否传入它。 method

protected virtual void Dispose(bool disposing)
{
    if (!_disposed)
    {
        _disposed = true;

        // Dispose the client
        HttpClient.Dispose();
        HttpClient = null;
        FirstMessageHandler = null;
        HttpClientHandler = null;
    }
}

我只是重写了“MyClient”中的 Dispose 方法而不执行任何操作,因为唯一被释放的对象是 HttpClient。

protected override void Dispose(bool disposing) { }

我没有注意到这有任何后果,因为 FirstMessageHandler 和 HttpClientHandler 仅在 ServiceClient 为您创建 HttpClient 时才会实例化。这种方法使我能够在多个 AutoRest 生成的 ServiceClient 中使用单个 HttpClient,并在每个请求上使用自定义用户凭据。

我很想知道是否有人看到这种方法的任何后果。

关于c# - 我们是否应该对 C# 中从 Microsoft.Rest.ServiceClient 派生的客户端使用单例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43484494/

相关文章:

c# - 在 Monomac/Xamarin C# 中创建无窗口菜单栏图标应用程序

azure - 如何使用 ARM 模板通过应用程序见解启用实时 Azure Web 应用程序分析

c# - Azure Blob TIFF 到 PNG 转换,无需下载

c# - 强事件和弱事件

c# - 从数据集中提取数据

c# - 是否有一种直接的方法来组合表示 15 分钟时间 block 的连续字符串值?

c# - 在.Net中设计 "Scalable Multi Threaded Socket Push Server"

c# - 如何在用户打开文件时锁定对文件的访问?

c# - .Net ORM 具有最快的学习曲线?

azure - 我们如何在 AZURE 中安排自定义代码调用认知 API