繁体   English   中英

我们是否应该为C#中的Microsoft.Rest.ServiceClient派生的客户使用Singletons?

[英]Should we use Singletons for clients derived from Microsoft.Rest.ServiceClient in C#?

使用swagger规范生成的Azure .NET SDK(例如与Azure Resource Manager关联的那些)时,生成的库利用Microsoft AutoRest Client Runtime,各种“Clients”都继承自“ServiceClient”。

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

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

注意:这个问题不是寻找关于单身人士或客户的一般开发人员建议的问题,而是基于对其内部工作的了解而与AutoRest客户端运行时相关联的Microsoft开发团队的特定问题。

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

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;

    }
    [...]
}

但是,这会在第一个请求之后导致ObjectDisposedException。 这是因为ServiceClient处理HttpClients,无论您是否传入它。 方法

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) { }

我没有发现任何后果,因为当ServiceClient为您创建HttpClient时,FirstMessageHandler和HttpClientHandler仅被实例化。 这种方法允许我在多个AutoRest生成的ServiceClient上使用单个HttpClient,并在每个请求上使用自定义用户凭据。

我有兴趣看看是否有人看到这种方法有任何后果。

是的,不是。 :-)您不需要使用Singleton设计模式,但建议尽可能共享ServiceClient派生的实例,因为每个实例都封装了一个HttpClient

对于某些Azure库,并不总是可以共享单个客户端。 例如, SearchIndexClient在Azure中搜索库只能指定一个索引的时间,因此,如果您的应用程序使用多个索引,你需要以某种方式汇集他们。 以下是有关此主题的相关问题,该问题与其他地方的其他讨论有关。

您现在可以在ServiceClient的实例之间共享HttpClient实例,因此不再有很大的理由使用单例模式

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM