简体   繁体   中英

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

I have a service class (AzureServiceBusService) that is instantiated by MEF and is used within ASP.NET Web Api controllers by injections. This class uses a TopicClient to send messages to an Azure Service Bus.

The documentation from Azure states that one should only use a single instance of the TopicClient to communicate with the Service Bus since a new connection is established for every new instance of the TopicClient .

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.

I know that per default the creation policy of MEF is shared so there should only by one instance in the MEF container available. I think that for each request a new controller instance is created and MEF wires together the imports within the controller. These instances should all be singletons by MEF's default configuration. After unsuccessful investigations about MEF, lifetime and usage of static properties within MEF, I ended up with the following design.

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();
    }
}

Those imports of the service are spread across the web application.

What is the correct design here? Do I need static properties at all to enforce singleton behaviour resulting in a single TopicClient instance? Can somebody shed some light on this?

Since documentation recommends the repeated use of the same instance of TopicClient I would make it a static as you have. While I acknowledge MEF should create one instance of your AzureServiceBusService class across the life of the application, I would still make TopicClient static to ensure all future uses will honor the documentation's recommendation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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