Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrating Simple injector with polly policies #729

Open
DanielLebon opened this issue Jun 24, 2019 · 4 comments

Comments

Projects
None yet
2 participants
@DanielLebon
Copy link

commented Jun 24, 2019

Hi,
I have a question about the good way to use Polly with Simple Injector.

I was thinking of doing it in the following way:

a) create all my Polly policies in a simple class like so:

public class Policies
{
    public readonly RetryPolicy<HttpResponseMessage> InternalServerErrorPolicy;
    public readonly RetryPolicy<HttpResponseMessage> RequestTimeoutPolicy;
    public Policies()
    {
        InternalServerErrorPolicy = Policy.HandleResult<HttpResponseMessage>(
           r => r.StatusCode == HttpStatusCode.InternalServerError)
           .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt));
        RequestTimeoutPolicy = Policy.HandleResult<HttpResponseMessage>(
            r => r.StatusCode == HttpStatusCode.RequestTimeout)
            .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(0.2, retryAttempt)));
    }
}

b) Register policies in simpleinjector with something like this :

container.Register< Policies>();

c) Use Policies as a constructor parameter

public class MyService
{
    private readonly Policies _policies;
    public MyService(Policies policies)
    {
        _policies = policies;
    }

Is this a good way to do it, can this work?

Thank you for your help.

@dotnetjunkie

This comment has been minimized.

Copy link
Collaborator

commented Jun 25, 2019

Can you explain why you want to inject the Policies class into Simple Injector? Why not do the following:

public static class Policies
{
    public static readonly RetryPolicy<HttpResponseMessage> InternalServerErrorPolicy =
        Policy.HandleResult<HttpResponseMessage>(
           r => r.StatusCode == HttpStatusCode.InternalServerError)
           .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt));

    public static readonly RetryPolicy<HttpResponseMessage> RequestTimeoutPolicy =
        Policy.HandleResult<HttpResponseMessage>(
            r => r.StatusCode == HttpStatusCode.RequestTimeout)
            .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(0.2, retryAttempt)));
}

public class MyService
{
    private readonly IOtherDependency dep;
    public MyService(IOtherDependency dep)
    {
        _dep = dep;
    }

    public void DoSomethingUsefull()
    {
        // Use policy
        Policies.InternalServerErrorPolicy.
    }
}

What is it that want you to inject the policy into your service's constructor?

@DanielLebon

This comment has been minimized.

Copy link
Author

commented Jun 25, 2019

Hi dotnetjunkie
Thank you for your reply.
Yes in Static indeed it will certainly work.
Just for my understanding, if the static mode can be used to do the dependency injection, is it recommended to do it without going through the container as Simpleinjector ?

@dotnetjunkie

This comment has been minimized.

Copy link
Collaborator

commented Jun 25, 2019

if the static mode can be used to do the dependency injection

The use of statics is not an application of Dependency Injection. You don't have to use Dependency Injection in every occassion. Dependency Injection is especially useful as technique on Volatile Dependencies. A Volatile Dependency is a dependency that you wish to be able to replace, mock, or Intercept, without having to change the original source code. (see: what to inject and what not to inject).

In your case, however, MyService was already tightly coupled with both the Policies class and the Polly classes. Injecting it would not help you much. That wouldn't reduce the amount of tight coupling.

Another option is to inject an RetryPolicy<HttpResponseMessage> directly into MyService's constructor, although I'm not sure this is a sensible thing to do with Polly (I'm not that familiar with the library). It still causes tight coupling to Polly, but would allow you to change the policy from inside your Composition Root without having to touch (or even recompile) the other modules in your application. This can be especially useful when you load the exact policy from a configuration file, as you only want the final application (i.e. the Composition Root) to take a dependency on the configuration file.

Injecting an RetryPolicy<HttpResponseMessage>, however, would complicate Simple Injector's configuration as you will likely have multiple services depending on the exact same type, but do require different policies on each of them. In Simple Injector, this can be achieved by using RegisterConditional.

@DanielLebon

This comment has been minimized.

Copy link
Author

commented Jun 26, 2019

Hi dotnetjunkie,
Thank you for this very clear and enriching analysis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.