Skip to content

GraphClientFactory.CreateDefaultHandlers should take IRequestOption[] parameter #1004

@ciborowskik

Description

@ciborowskik

Is your feature request related to a problem? Please describe the problem.

I am trying to add custom RetryHandlerOption() globally for all calls from my C# app.

There is a method GraphClientFactory.CreateDefaultHandlers() that creates default http handlers for GraphServiceClient, among others RetryHandler. The thing is that there is no way to put retry options in parameters. I could replace default RetryHandler with new object that takes my custom RetryHandlerOption. Something like that:

RetryHandlerOption retryHandlerOption = new RetryHandlerOption()
{
    MaxRetry = 7,
    Delay = 7,
    ShouldRetry = (delay, attempt, httpResponse) => false
};

var handlers = GraphClientFactory.CreateDefaultHandlers();
var retryHandler = handlers.OfType<RetryHandler>().FirstOrDefault();
if (retryHandler != null)
{
    var index = handlers.IndexOf(retryHandler);
    handlers.RemoveAt(index);
    handlers.Insert(index, new RetryHandler(retryHandlerOption));
}
var httpClient = GraphClientFactory.Create(handlers);

var client = new GraphServiceClient(httpClient, clientCertCredential);

... but it doesn't look good.

Describe the solution you'd like.

GraphClientFactory.CreateDefaultHandlers() uses KiotaClientFactory.CreateDefaultHandlers() under the hood, which can take IRequestOption[] as a parameter:

public static IList<DelegatingHandler> CreateDefaultHandlers(IRequestOption[]? optionsForHandlers = null)
{
    optionsForHandlers ??= Array.Empty<IRequestOption>();

    UriReplacementHandlerOption? uriReplacementOption = null;
    RetryHandlerOption? retryHandlerOption = null;
    RedirectHandlerOption? redirectHandlerOption = null;
    ParametersNameDecodingOption? parametersNameDecodingOption = null;
    UserAgentHandlerOption? userAgentHandlerOption = null;
    HeadersInspectionHandlerOption? headersInspectionHandlerOption = null;
    BodyInspectionHandlerOption? bodyInspectionHandlerOption = null;

    foreach(var option in optionsForHandlers)
    {
        if(uriReplacementOption == null && option is UriReplacementHandlerOption uriOption)
            uriReplacementOption = uriOption;
        else if(retryHandlerOption == null && option is RetryHandlerOption retryOption)
            retryHandlerOption = retryOption;
        else if(redirectHandlerOption == null && option is RedirectHandlerOption redirectOption)
            redirectHandlerOption = redirectOption;
        else if(parametersNameDecodingOption == null && option is ParametersNameDecodingOption parametersOption)
            parametersNameDecodingOption = parametersOption;
        else if(userAgentHandlerOption == null && option is UserAgentHandlerOption userAgentOption)
            userAgentHandlerOption = userAgentOption;
        else if(headersInspectionHandlerOption == null && option is HeadersInspectionHandlerOption headersInspectionOption)
            headersInspectionHandlerOption = headersInspectionOption;
        else if(bodyInspectionHandlerOption == null && option is BodyInspectionHandlerOption bodyInspectionOption)
            bodyInspectionHandlerOption = bodyInspectionOption;
    }

    return new List<DelegatingHandler>
    {
        uriReplacementOption != null ? new UriReplacementHandler<UriReplacementHandlerOption>(uriReplacementOption) : new UriReplacementHandler<UriReplacementHandlerOption>(),
        retryHandlerOption != null ? new RetryHandler(retryHandlerOption) : new RetryHandler(),
        redirectHandlerOption != null ? new RedirectHandler(redirectHandlerOption) : new RedirectHandler(),
        parametersNameDecodingOption != null ? new ParametersNameDecodingHandler(parametersNameDecodingOption) : new ParametersNameDecodingHandler(),
        userAgentHandlerOption != null ? new UserAgentHandler(userAgentHandlerOption) : new UserAgentHandler(),
        headersInspectionHandlerOption != null ? new HeadersInspectionHandler(headersInspectionHandlerOption) : new HeadersInspectionHandler(),
        bodyInspectionHandlerOption != null ? new BodyInspectionHandler(bodyInspectionHandlerOption) : new BodyInspectionHandler(),
    };
}

Current code of GraphClientFactory:

public static IList<DelegatingHandler> CreateDefaultHandlers(GraphClientOptions graphClientOptions = null)
{
    var handlers = KiotaClientFactory.CreateDefaultHandlers();
    handlers.Add(new GraphTelemetryHandler(graphClientOptions));// add the telemetry handler last.

    return handlers;
}

Feature request:

public static IList<DelegatingHandler> CreateDefaultHandlers(GraphClientOptions graphClientOptions = null, IRequestOption[]? optionsForHandlers = null)
{
    var handlers = KiotaClientFactory.CreateDefaultHandlers(optionsForHandlers );
    handlers.Add(new GraphTelemetryHandler(graphClientOptions));// add the telemetry handler last.

    return handlers;
}

Then we could do:

RetryHandlerOption retryHandlerOption = new RetryHandlerOption()
{
    MaxRetry = 7,
    Delay = 7,
    ShouldRetry = (delay, attempt, httpResponse) => false
};

var handlers = GraphClientFactory.CreateDefaultHandlers([retryHandlerOption]);
var httpClient = GraphClientFactory.Create(handlers);

var client = new GraphServiceClient(httpClient, clientCertCredential);

Additional context?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions