Closed svrooij closed 4 months ago
For other readers, this is the context this request comes from I think this is a reasonable request, especially if we collocate the new method next to the create one. From a naming convention perspective, it should be prefixed with a Get.
Is this something you'd be willing to submit a pull request for @svrooij ?
Love this idea!
And related to this, do you ever expect the UriReplacementHandler<UriReplacementHandlerOption>
to have other options @sebastienlevert? The generic is a bit in the way to make this happen. And the constructor for this one is using = default
while all the others use = null
. The first one doesn't play nice with dependency injection, but that could also because of the generic.
@calebkiage might be able to add more context on why the option is a generic type parameter and what scenarios he was trying to enable making it generic here. #158
@svrooj, the IUriReplacementHandlerOption
is an extensibility point. For example, a user could decide to implement it and then change IsEnabled
to be conditional on different circumstances. The default implementation of UriReplacementHandlerOption
has a fixed value for IsEnabled
for each instance passed to the constructor. It's also possible to change the Replace
function's logic through a different implementation. The UriReplacementHandler
is generic to allow swapping out the type of IUriReplacementHandlerOption
. What problems are you having with the DI setup?
@calebkiage I'm trying to document how you can use Microsoft.Extensions.Http and dependency injection in general with Kiota. @baywet suggested that it was a bad idea to document a static list of handlers. So I tried injecting the types, from CreateDefaultHandlers()
using .Select(x => x.GetType())
.
But it does not take it, won't resolve the UriReplacementHandler<UriReplacementHandlerOption>
, not sure if it has to do with the constructor having = default
instead of = null
or with the generic being in the way.
Without the generic type and with =null
constructor, it could resolve the handler without options unless the developer explicitly added the UriReplacementHandlerOption
to the DI container as well.
And when thinking about it, if a developer wants to use the UriReplacementHandler
with other options type, he/she can no longer use the CreateDefaultHandlers(), method because then he/she would have to inject another handler.
We could still enable the extensibility while enabling that scenario and without shipping a breaking change simply by:
Thoughts?
I suspect the root cause here might be the UriReplacementHandlerOption
not having a default constructor. The dependency graph of UriReplacementHandler
would be:
UriReplacementHandler
|
UriReplacementHandlerOption
|
----------------------------------------------
| |
bool IEnumerable<KeyValuePair<string, string>>
The DI library won't know how to create an instance of UriReplacementHandlerOption
because it can't resolve the constructor parameters.
I'd need to create a project to reproduce this and investigate. @svrooij, if you have a project on GitHub, I can just use that to quickly reproduce the issue and provide my suggestions.
@baywet, your idea would work, but we also need the derived handler to provide a default value for the option type
Right, we could start with the constructor and see if that fixes things by just adding another constructor
public UriReplacementHandlerOption(bool isEnabled = true):this(isEnabled, new Dictionary<string, string>())
Kiota opted for it's own HttpClientFactory, which is fine. But I would like to integrate with dependency injection and start using
Microsoft.Extensions.Http
as a source for the HttpClient. To keep all the Kiota goodies like (header inspection) I need to register all the Kiota handlers as well.For that I only need the types of the handlers, and not the instances. Would it be possible to have an extra static method just for that? Instead of this:
https://github.com/microsoft/kiota-http-dotnet/blob/0212e818931b31a2d9e0ab4d768b31f23fe5f386/src/KiotaClientFactory.cs#L50-L62
I would like to see, as this does not initialize those classes.