我是否需要在 Mef 实例化 class 中使用静态 TopicClient 属性 来强制在我的 Web 应用程序中使用单个 TopicClient?

Do I need a static TopicClient property in an Mef instantiated class to enforce the use of a single TopicClient in my web application?

我有一个服务 class (AzureServiceBusService),它由 MEF 实例化并通过注入在 ASP.NET Web Api 控制器中使用。此 class 使用 TopicClient 将消息发送到 Azure 服务总线。

来自 Azure 的 documentation 声明应该只使用 TopicClient 的单个实例与服务总线通信,因为 [=13] 的每个新实例都会建立一个新连接=].

Service Bus client objects, such as QueueClient or MessageSender, are created through a MessagingFactory object, which also provides internal management of connections. You should not close messaging factories or queue, topic, and subscription clients after you send a message, and then re-create them when you send the next message. Closing a messaging factory deletes the connection to the Service Bus service, and a new connection is established when recreating the factory. Establishing a connection is an expensive operation that you can avoid by re-using the same factory and client objects for multiple operations. You can safely use the QueueClient object for sending messages from concurrent asynchronous operations and multiple threads.

我知道默认情况下 MEF 的创建策略是共享的,因此 MEF 容器中应该只有一个实例可用。我认为对于每个请求,都会创建一个新的控制器实例,并且 MEF 会将控制器内的导入连接在一起。根据 MEF 的默认配置,这些实例都应该是单例。在对 MEF、生命周期和 MEF 中静态属性的使用进行了不成功的调查后,我最终得出了以下设计。

public class AzureServiceBusService : IAzureServiceBusService
{
    private static readonly _topicClient;

    static AzureServiceBusService()
    {
        _topicClient = TopicClient.CreateFromConnectionString(sbConnectionString, sbTopicPath);
    }

    public async Task SendAsync(BrokeredMessage msg)
    {
        _topicClient.SendAsync(msg);
    }
}

public class ApiController
{
    [Import]
    public IAzureServiceBusService AzureServiceBusService {get; set;} 

    public async Task<HttpResponseMessage> SendEvent()
    {
        await AzureServiceBusService.SendAsync(new BrokeredMessage());
        return new HttpResponseMessage();
    }
}

这些服务的导入分布在 Web 应用程序中。

这里正确的设计是什么?我是否需要静态属性来强制执行导致单个 TopicClient 实例的单例行为?有人可以解释一下吗?

由于文档建议重复使用 TopicClient 的同一个实例,因此我会像您一样将其设为静态。虽然我承认 MEF 应该在应用程序的整个生命周期中创建一个 AzureServiceBusService class 的实例,但我仍然会将 TopicClient 设为静态以确保所有未来的使用都将遵守文档的建议。