Search code examples
c#.netdependency-injectionflurllibrary-design

Library design and DI with 3rd party dependencies


I'm writing a library for internal use. The purpose of this library is to abstract away calls to some internal REST API's. Under the hood, I'm using Flurl to make the requests. The library also provides extensions methods that sets up DI (Core Web) to easily wire everything together (services.AddXYIntegration()). In case of flurl, my library provides an implementation of DefaultHttpClientFactory (inherits from IHttpClientFactory) => X509ClientFactory. To avoid collision or overwriting DI of applications using my library that probably also use Flurl for https requests and want to provide a custom implementation for IHttpClientFactory I created an empty interface just to "mark" my libraries implementation and use that in the DI wiring.

Little bit code:

public interface IX509HttpClientFactory : IHttpClientFactory 
{
    // empty interface, violates CA1040
}

public class X509HttpClientFactory : DefaultHttpClientFactory /* inherits from IHttpClientFactory */, IX509HttpClientFactory
{
    // Implementation details...
}

So, instead of injecting X509HttpClientFactory for IHttpClientFactory , the library creates the instance for IX509HttpClientFactory. IHttpClientFactory is still "available" for injection.

My question is not specific to flurl, it's more a general question for similar scenarios.

Is this a good design? How do you handle such cases where you have configurable 3rd party dependencies? Is it a feasible scenario to violate CA1040.


Solution

  • So, instead of injecting X509HttpClientFactory for IHttpClientFactory, the library creates the instance for IX509HttpClientFactory.

    If I'm understanding you correctly, then yes, I think this is the way to go. DI is an application-level concept, and although we're conditioned to use it to instantiate most things, it's still totally appropriate to new up dependencies internal to a library in order to keep that library well encapsulated. I wouldn't even expose IX509HttpClientFactory publicly unless there's a need to that I'm not seeing.