lundi 5 mars 2018

Writing a client wrapper class to isolate internal details of the client whose class implements IDisposable but interface does not

I am writing a client wrapper around an external client that is defined in a NuGet package. The NuGet package contains below interface and the class.

public interface IServiceClient
{
    Task<Job> CreateJobAsync(JobDetails jobdetails);
}

public class ServiceClient : IServiceClient, IDisposable
{
    public async Task<Job> CreateJobAsync(JobDetails jobDetails)
    {   
        // Some processing and returns a job that contains required response and status

        return job;
    }
}

In my application, I write a client wrapper around the service client as below:

public interface IServiceClientWrapper
{
    Task<ResponseDto> PostAsync(RequestDto request);
}

public class ServiceClientWrapper : IServiceClientWrapper
{
    private static IServiceClient serviceClient;

    public static void Init()
    {
        // See below for defintion
        serviceClient = ClientFactory.Create();
    }   

    public async Task<ResponseDto> PostAsync(RequestDto request)
    {
        // Convert request to JobDetails as required

        var job = await serviceClient.CreateJobAsync(jobDetails);

        // Convert job to ResponseDto and return
        return response;
    }

    // Since ServiceClient implements IDisposable
    public static void Close()
    {
        if (serviceClient != null)
        {
            ((ServiceClient)serviceClient).Dispose();
        }
    }
}

internal static class ClientFactory
{   
    public static IServiceClient ServiceClient { get; set; }

    public static IServiceClient Create()
    {
        if (ServiceClient != null)
        {
            // Used during unit testing
            return ServiceClient;
        }

        return new ServiceClient(APIBaseAddress, AccessKey);
    }
}

Questions:

  1. Since the interface isn't marked IDisposable, I introduce Init and Close methods to do that. Is there a better way to handle this?

  2. Having the serviceClient as static, is it thread-safe since I always invoke the non-static CreateJobAsync method with new paramters for each request?

Aucun commentaire:

Enregistrer un commentaire