Home > OS >  How to close connection of a WCF client instantiated via interface?
How to close connection of a WCF client instantiated via interface?

Time:10-27

I have a WCF client that has been instantiated via its interface on my MVC 4 project controller like this:

private readonly ILMS_Service lms_client;

public ProductsController(ILMS_Service client)
{
    lms_client = client;
}

public ProductsController()
{
    lms_client = new LMS_ServiceClient();
}

I can access the operation contracts from the client, but what I noticed on this implementation is that there's no .Open() and .Close() methods as I would normally access with LMS_Client lms_client = new LMS_ServiceClient();. I cannot use this conventional way initializing the WCF client since I need to be able to pass mock WCF client from my unit tests. With this, I have to initialize the WCF client via it's interface and have to make a constructor to pass the mock service whenever I test.

Correct me if I'm wrong but I have found this post, however it doesn't tell me anything where to implement the Dispose() method (e.g. to the Controller or on the .svc file of the WCF project?). And I think this answer doesn't seem to have unit testing in mind. It seems to implement the interface for every call of the methods on the WCF; in which, it is not mockable. In addition, I have also found this blog which is the closest to my scenario, but is this a good way of closing the connection via a destructor? Where do you implement it? On the Controller calling the method or the on the .svc file of the WCF project?

It would be great if someone could enlighten me or show me a good way of opening/closing WCF client connection with this implementation through an example. Any help would be appreciated. Thanks!

CodePudding user response:

I think you can use close and abort to release wcf client resources as suggested by Microsoft documentation. https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/use-close-abort-release-wcf-client-resources

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

The first link you provided is basically creating a partial class for the WCF client and then inheriting the Dispose method.
For details, you can check the documentation: https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose

CodePudding user response:

I found a way to close the connection of the WCF service if you are using it via interface. You can use the Dispose method on the class and cast your WCF service interface to the actual implementation.

private readonly ILMS_Service lms_client;

public ProductsController(ILMS_Service client)
{
    lms_client = client;
}

public ProductsController()
{
    lms_client = new LMS_ServiceClient();
}

protected override void Dispose(bool disposing)
{
    if (disposing) {
        var clientObject = lms_client as LMS_ServiceClient;
        if (clientObject != null && clientObject.State == System.ServiceModel.CommunicationState.Opened)
        {
            clientObject.Close();
        }
    }
}

When closing the WCF connection, I suggest you follow @Lan Huang's answer or @Rico Sutter's answer here, the same can be found on @Rico Sutter's blog

  • Related