Search code examples
c#dependency-injectionpollyretry-logicrefit

How do I add a Polly policy to a Refit Client created with a factory?


I have a refit client (IMyRefitClient) that returns

Task<ApiResponse<ADomainModel>>

I can't inject this refit client in Program.cs with HostBuilder.ConfigureServices because the url isn't known until runtime. Therefore, I'm using a factory class like:

return RestService.For<IMyRefitClient>(hostUrl);

I know how to add a policy in ConfigureServices. It would look like:

services.AddRefitClient<IMyRefitClient>()
        .AddPolicyHandler(PollyHelpers.GetRetryPolicy());

Is there a way that I can add this policy when using the factory class?


Solution

  • Polly has a concept of PolicyRegister, which is basically a IEnumerable<KeyValuePair<string, IsPolicy>> collection.

    So, it is a container where you can register policies with arbitrary names:

    var register = new PolicyRegistry()
    {
        { "CB_aware_Retry", GetRetryPolicy() },
        { "500_aware_CB", GetCircuitBreakerPolicy() },
        { "Retry_CB_combined", Policy.WrapAsync(GetRetryPolicy(), GetCircuitBreakerPolicy()) }
    };
    

    On the ServiceCollection you can register a new container or an existing one:

    services.AddPolicyRegistry(registry)
    

    You can access the policies by relying on the IReadOnlyPolicyRegistry:

    public class MyRefitClient 
    {
        private readonly IAsyncPolicy<ApiResponse<ADomainModel>>> combined;
        public MyRefitClient(..., IReadOnlyPolicyRegistry<string> registry, ...)
        {
           ...
           combined = registry.Get<IAsyncPolicy<ApiResponse<ADomainModel>>>>("Retry_CB_combined");
        } 
    }