Search code examples
c#wcfdependency-injection.net-core

Safely release dependency injected wcf client in .net core


I want to use Microsoft's dependency injection in .Net Core (2.2) to inject and safely release WCF clients. I'm using the "WCF Web Service Reference Provider Tool" in VS2019 to add WCF proxy classes to my solution. Using Microsoft.Extensions.DependencyInjection I can register the clients in the services collection, but I can't seem to find a way of hooking into a release lifecycle event (as can be done in various other IoC frameworks, e.g. Autofac), to add code for doing a safe release according to Microsoft's recommendations described here: https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/use-close-abort-release-wcf-client-resources

Is there any way of doing something like that in the quite basic dependency injection functionality that comes with .Net Core framework? Or am I forced to use 3rd party IoC framework?

Pseudo code:

So basically I want to do something like this:

// Register the channel factory for the service. Make it
// Singleton since you don't need a new one each time.
services.AddSingleton(p => new ChannelFactory<IWcfService>(
    new BasicHttpBinding(),
    new EndpointAddress("http://localhost/WcfService")));

// Register the service interface using a lambda that creates
// a channel from the factory.
// TODO: need a way to handle proper disposal, e.g. like OnRelease().
services.AddTransient<IWcfService>(p => 
        p.GetService<ChannelFactory<IWcfService>>().CreateChannel())
    .OnRelease(CloseChannel); // <---This is what I would like to do

static void CloseChannel<T>(T channel)
{
    var disp = (ICommunicationObject) channel;
    try
    {
        if (disp.State == CommunicationState.Faulted)
            disp.Abort();
        else
            disp.Close();
    }
    catch (TimeoutException)
    {
        disp.Abort();
    }
    catch (CommunicationException)
    {
        disp.Abort();
    }
    catch (Exception)
    {
        disp.Abort();
        throw;
    }
}

But I need a way to hook into the service release lifecycle event, e.g. something like .OnRelease() in Autofac, so I can do proper disposal.


Solution

  • I dont know if you still need a response, but on my end to resolve this issue I implemented the dispose into the partial class.

    Each time the wcf client is disposed the correct clean up is made:

      public partial class MyWcfClient : IDisposable
    {
        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                bool success = false;
                try
                {
                    if (State != CommunicationState.Faulted)
                    {
                        Close();
                    }
    
                    success = true;
                }
                finally
                {
                    if (!success)
                    {
                        Abort();
                    }
                }
            }
        }
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }