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.
So, instead of injecting
X509HttpClientFactory
forIHttpClientFactory
, the library creates the instance forIX509HttpClientFactory
.
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.