Update to allow greater flexibility in HttpClient registration #1610
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
As a best practice, it's a good idea to create all
HttpClient
instances from anIHttpClientFactory
for the reasons listed here. Today's version of Dapr doesn't do this across any of the packages, with the exception of sort of doing this inDapr.Workflow
.Because we use a factory approach to creating the
DaprClient
itself that exposes methods for specifying the Dapr API token, declaring the timeout value or specifying the gRPC/HTTP endpoints, among other options, we lack any functionality that might be exposed to the user to do a more elaborate configuration of theHttpClient
that's produced.At the same time, I hesitate to simply apply a global configuration against an
IHttpClientFactory
as it would apply to all clients. One aspect of how I've built out Dapr DI so far is to enable the developer to point to different endpoints to use different aspects of Dapr (e.g. use the sidecar to instantiate aDaprClient
for state management, but point to Diagrid's Catalyst platform to process workflow operations). Having a global configuration against theIHttpClientFactory
would negate this capability as one settings configuration would rein over all implementations.The compromise made here is to support an
IDaprHttpClientFactory
. When the developer registers Dapr usingAddDaprClient()
or indirectly does the same by calling any of the variousAddDapr*()
methods in each of the packages (which generally all take a dependency onAddDaprClient()
as well), this also registers theIDaprHttpClientFactory
which accepts the sameAction<IServiceProvider, HttpClient>
parameter that theAddHttpClient()
accepts, allowing the user to apply a custom configuration to the client. The client they're modifying will have already been updated with the Dapr configuration, so any custom configuration will take precedence over this setup, but the option is then there for developers to take advantage of.Should said developer wish to have an instance of the
HttpClient
for their own purposes, merely injectIDaprHttpClientFactory
into their type and use the returnedHttpClient
from theCreateClient()
method.This implementation is provided as a proof-of-concept of the latest generation of this idea and needs both best practice documentation and unit testing before it should be merged.
Issue reference
We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.
Please reference the issue this PR will close: #1484
Checklist
Please make sure you've completed the relevant tasks for this PR, out of the following list: