Using Polly with Any Type of Request

Full source code here.

I recently presented a talk on Polly at the DevUp conference in St. Louis. In the presentation I showed examples using Polly with HttpClient requests only because this is my most common use case. I showed how to use retries, circuit breakers, fallbacks, caching, timeouts and bulkheads isolation. At the end of the presentation a few people asked me if Polly could be used with other types of request, of course it can and I should have said so during the talk. I’ve added new slide for the next time I present on Polly – (as of October 2018 that will be Granite State Code Camp, Boston Code Camp and NDC London).

Polly can be used with any type of request you make, whether it returns a value or not. You can use on code that throws exceptions from time to time (though I strongly recommend fixing your code), for database calls, any method call for that matter. Below are some examples of using the retry policy in a variety of scenarios.

Exceptions
This policy retries if an exception is thrown, you can be more specific about exception types.

 
RetryPolicy retryIfException = Policy.Handle<Exception>()
    .Retry(4, (exception, retryCount) =>
    {
        Console.WriteLine($"Got a response of {exception.Message} (expected 0), retrying {retryCount}");
    });

Int
Here I check check if the int returned is anything other than 0, or if there has been a DivideByZeroException. If so, I retry up to four times and also print some text to console.

 
RetryPolicy<int> retryPolicyNeedsAResponseOfOne = Policy.HandleResult<int>(i => i != 0)
    .Or<DivideByZeroException>()
    .Retry(4, (response, retryCount) =>
    {
        Console.WriteLine($"Got a response of {response.Result} (expected 0), retrying {retryCount}");
    });

IEnumerable
In this one I check that the IEnumerable has three items in it, if not, I retry and print some info to the console.

 
RetryPolicy<IEnumerable<int>> retryPolicyNeedsResponeWithTwoNumbers = Policy.HandleResult<IEnumerable<int>>(l => l.Count() != 3)
   .Retry(4, (response, retryCount) =>
   {
       Console.WriteLine($"Got a reponse with {response.Result.Count()} entries (expected 3), retrying {retryCount}");
   });

Bool
In this policy I check the bool returned, if it is false, I retry.

 
RetryPolicy<bool> retryPolicyNeedsTrueResponse = Policy.HandleResult<bool>(b => b != true)
   .Retry(4, (response, retryCount) =>
   {
       Console.WriteLine($"Got a reponse of {response.Result} entries (expected true), retrying {retryCount}");
   });

Polly can check the value of any return type or exception making it possible to use Polly for any call you can think of.

Full source code here.

Saving Enums with Entity Framework Core

Full source code here.

A few years ago I wrote a post about saving enums to the database with Entity Framework. It was able to save the enum as a string to the database and when reading from the database it was able to take that string and populate the enum correctly. It worked fine but felt a bit hacky.

With Entity Framework Core there is a neater and nicer way to do this using value conversions.

Let’s say we have an Address with two enums – AddressType and DeliveryPreference.

public partial class Address
{
    public int AddressId { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public AddressType AddressType { get; set; }
    public DeliveryPreference DeliveryPreference { get; set; }
}

We can save the enums to the database as either strings or ints, and when reading them back populate the enum! Here’s how to do both.

The table
My table looks like this

As you can see, the AddressType is stored as an int and the DeliveryPreference is stored as a string.

When you run the application it should create the database and table for you, but in case you don’t have your permissions setup correctly, here’s the script to create it.

CREATE TABLE [dbo].[Address] (
    [AddressId]          INT            IDENTITY (1, 1) NOT NULL,
    [Line1]              VARCHAR (50)   NOT NULL,
    [Line2]              VARCHAR (50)   NOT NULL,
    [AddressType]        INT            NOT NULL,
    [DeliveryPreference] VARCHAR (50) NOT NULL,
    CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED ([AddressId] ASC)
);

Saving an enum as an string
Firstly lets look at saving the DeliveryPreference enum as an string.

In the context we build the entity, I have the usual things you would expect for AddressId, Line1 and Line2. But DeliveryPreference is a little different.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Address>(entity =>
    {
        entity.Property(e => e.AddressId).ValueGeneratedOnAdd();

        entity.Property(e => e.Line1)
            .IsRequired()
            .HasMaxLength(50)
            .IsUnicode(false);

        entity.Property(e => e.Line2)
            .IsRequired()
            .HasMaxLength(50)
            .IsUnicode(false);

        entity.Property(e => e.DeliveryPreference) 
            .HasMaxLength(50)
            .HasConversion(x => x.ToString(), // to converter
                x => (DeliveryPreference) Enum.Parse(typeof(DeliveryPreference), x));// from converter

	    //snip..

The DeliveryPreference uses the HasConversion method, passing it two parameters.
The first parameter is the convert to provider expression which as the name suggests converts the value in our object to the type you will store in the database.

And the second is the convert from provider expression, it converts the the type in database to the type in your class.

In this example, I cast the enum to an string to store in the database, and when retrieving from the database I cast the stored string to an DeliveryPreference enum.

Saving an enum as an int
For the second enum, AddressType I don’t explicitly need to convert it from an enum to an int, Entity Framework will do this automatically (as pointed out to me in this tweet). But I’m including it as an example in case you need something like this for some other explicit conversion.

In this example, I cast the enum to an int to store in the database, and when retrieving from the database I cast the stored int to an AddressType enum.

// this is a continuation of the OnModelCreating method
        entity.Property(e => e.AddressType)
            .HasConversion(x => (int) x, x => (AddressType) x);

Full source code here.

Performance Comparison of Entity Framework Core 2.1 and Dapper 1.5

tl;dr – ignore most (maybe all) of the posts out there comparing Dapper and Entity Framework performance, you need to measure it yourself.
Here’ why –
1. Some are angry opinion pieces from people who don’t like one technology or the other and clearly haven’t run any tests.
2. All are out of date (as this one will be shortly) because the libraries move so quickly.
3. None are running against the database and network you have.
4. Your standard queries are far more important than whatever arbitrary queries they used.

Longer Version
I recently had to decide between a few different ORMs for a project, the specifics of the project are irrelevant, but I was using a Postgres database that had lots of data (my lots and your lots are probably different, that I had hundreds of millions of records should not matter to you).

Most of the posts comparing Dapper and EF that I read came down on the side of Dapper, some by a tiny margin and one by no margin but a lot of bluster.

Rather than trust any of these posts I wrote my own benchmarking application using the BenchmarkDotNet library.

I picked seven of the most representative queries I was making and coded them up in both Dapper and EF. Some of the queries pulled back tens of thousands of records and some brought back scores of records, but the most important thing was that these were queries I was going to run in the finished application.

BenchmarkDotNet takes care of things making sure the code has been jitted, that everything has been “warmed up” and then it runs the same request repeatedly to get a useful average.

On top of this, I ran the whole suite of benchmarking tests multiple time, at different times of the day because my application does not live in a vacuum, I needed to know how it would react when the network or database is under more or less load.

At the end of all this Entity Framework came out on top; for the vast majority of test runs it performed better.

Here are the results of one of the test runs, I didn’t pick the best or the worst, but this one is is indicative of what I saw for the majority of tests.

MethodMeanErrorStdDevMedian 
EF_Query1431.19 ms 13.9615 ms38.1581 ms 445.98 ms
Dapper_Query1689.88 ms 35.9716 ms102.7689 ms668.13 ms
EF_Query245.21 ms 1.5613 ms4.6816 ms46.35 ms
Dapper_Query261.55 ms1.7915 ms5.0850 ms62.19 ms
EF_Query3278.72 ms 51.4681 ms150.8833 ms351.38 ms
Dapper_Query3298.64 ms7.3619 ms20.2561 ms297.15 ms
EF_Query417.97 ms 0.3570 ms0.6310 ms17.93 ms
Dapper_Query426.59 ms 0.6516 ms1.7592 ms25.78 ms
EF_Query570.78 ms 1.4936 ms4.0985 ms71.21 ms
Dapper_Query5116.71 ms2.5632 ms7.4015 ms116.36 ms
EF_Query6189.71 ms50.1289 ms148.7825 ms311.21 ms
Dapper_Query6248.61 ms7.2891 ms21.1751 ms304.16 ms
EF_Query7266.62 ms6.2219 20.3179 ms281.27 ms
Dapper_Query7304.27 ms7.8163 ms15.1561 ms301.21 ms

I was a little surprised at this result, but there you have it. EF Core 2.1 is better for me than Dapper.

Out of interest, I took a small portion of my data and put it into SqlServer, and re-ran the tests. This time, Dapper came out slightly ahead. But the SqlServer is on a different network than the Postgres db, is under different load and had a much small dataset so not a realistic exercise.

Conclusion
The moral of the story is you have to test performance yourself, there is absolutely no way you can extrapolate from a test someone wrote about in a blog (including this one) when judging how an ORM will perform for you.

Polly, HttpClientFactory and the Policy Registry – choosing the right policy based on the HTTP request

Full source code available here.

The release of .NET Core 2.1 has made using HttpClient much easier. If you have been using HttpClient for a while you will know about its limitations around reuse and DNS expiry, I wrote about this some time ago. The HttpClientFactory takes care of the problems addressed in that post.

Along with those improvements the HttpClientFactory now makes it very easy to add Polly policies that will be executed whenever you create a HttpClient with the factory. This means you define the polices in one place, add them to the factory and forget about them! No more code is needed to add resilience to each of your calls. The factory takes care of creating the client and applying the policy, you can’t even tell that Polly is protecting your call where you make it.

For more on the HttpClientFactory check out Steve Gordon’s series of articles.

A simple example
Here’s a simple example of the HttpClientFactory in use. This adds the factory to our dependency injection container, sets the base address of the remote server and lets us configure the client. It also adds a simple retry policy that checks if the response is NOT a success code and retries up to three times.

services.AddHttpClient("OrderApiServer", client =>
{
    client.BaseAddress = new Uri("http://localhost:57696/api/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
}).AddPolicyHandler(Policy.HandleResult<HttpResponseMessage>
    (r => !r.IsSuccessStatusCode).RetryAsync(3));

When you create a HttpClient now, it will include the policy.

var httpClient = _httpClientFactory.CreateClient("OrderApiServer");

And when you execute a request it the policy will retry up to three times if necessary.

var result = await httpClient.GetAsync("api/SomeEndpoint);

This might be great if all you are going to is perform GET’s and every call you make is safe and idempotent. But what if you want to use GET, PUT, POST and DELETE, you won’t want to retry all of those requests?

This is easy too. You add a policy registry will all the policies you want to use. Say, a retry policy, a wait and retry policy and no op policy, and provide a selector method to pick the right one based on the HTTP verb (or even the endpoint you are requesting).

Using a Policy Registry with the HttpClientFactory

Step 1

Add the policy registry to the Service Collection and add the policies to the registry.

public void ConfigureServices(IServiceCollection services)
{
    IPolicyRegistry<string> registry = services.AddPolicyRegistry(); // creates the registry and adds it to the service collection

    IAsyncPolicy<HttpResponseMessage> httpRetryPolicy =
        Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
            .RetryAsync(3);

    registry.Add("SimpleHttpRetryPolicy", httpRetryPolicy);

    IAsyncPolicy<HttpResponseMessage> httWaitAndpRetryPolicy =
        Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
            .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt));

    registry.Add("SimpleWaitAndRetryPolicy", httWaitAndpRetryPolicy);

    IAsyncPolicy<HttpResponseMessage> noOpPolicy = Policy.NoOpAsync()
        .AsAsyncPolicy<HttpResponseMessage>();

    registry.Add("NoOpPolicy", noOpPolicy);
    //snip..

Step 2
Now that we have the three polices and the registry, lets add the HttpClientFactory to the Service Collection.

services.AddHttpClient("OrderApiServer", client =>
{
    client.BaseAddress = new Uri("http://localhost:57696/api/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
}).AddPolicyHandlerFromRegistry(PolicySelector);

Note the PolicySelector, this is the method I use to choose the right policy for each request.

Step 3
This method is simple, it takes the registry and the HttpRequest as arguments and grabs the policy from the registry based on the HTTP verb.

private IAsyncPolicy<HttpResponseMessage> PolicySelector(IReadOnlyPolicyRegistry<string> policyRegistry, HttpRequestMessage httpRequestMessage)
{
    if (httpRequestMessage.Method == HttpMethod.Get)
    {
        return policyRegistry.Get<IAsyncPolicy<HttpResponseMessage>>("SimpleHttpRetryPolicy");
    }
    else if (httpRequestMessage.Method == HttpMethod.Post)
    {
        return policyRegistry.Get<IAsyncPolicy<HttpResponseMessage>>("NoOpPolicy");
    }
    else
    {
        return policyRegistry.Get<IAsyncPolicy<HttpResponseMessage>>("SimpleWaitAndRetryPolicy");
    }
}         

You could use a lambda instead of a method when creating the HttpClientFactory. For example if if you had two policies to choose from –

.AddPolicyHandlerFromRegistry((policyRegistry, message) => policyRegistry.Get<IAsyncPolicy<HttpResponseMessage>>(message.Method == HttpMethod.Get ? "SimpleHttpRetryPolicy" : "NoOpPolicy"));

That’s the hard work done.

Step 4
Let’s take a look at the controller.

public class OrderController : ControllerBase
{
    private readonly IHttpClientFactory _httpClientFactory;

    public OrderController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }


    [HttpGet("{orderId}")]
    public async Task<ActionResult> Get(int orderId)
    {
        //snip
        string requestEndpoint = $"invoice/{orderId}";

        var httpClient = _httpClientFactory.CreateClient("OrderApiServer");

        HttpResponseMessage response = await httpClient.GetAsync(requestEndpoint);

		//handle response
    }	
}

The only thing I’m passing into the constructor is the HttpClientFactory, I don’t have any Polly using statements.

In the GET method you can’t even tell that there is a policy around the HttpClient.GetAsync(..)

All the Polly work is done in the Startup.cs, the policies are defined, added to the registry, the registry is added to the HttpClientFactory and the HttpClientFactory is added to the services collections.

Now all your HttpClient requests are executed inside a policy.

For more on this, check out Dylan’s Polly and HttpClientFactory documentation.

Full source code available here.

Loading Config from Multiple Sources with .NET Core 2.x Web Api or MVC

Full source code available here.

.NET Core 2 and .NET Core 2.1 offer many ways to load configuration and they are well documented by Microsoft. But there is one scenario that I didn’t see explained.

If you want to supplement the configuration in appsettings.json with more from a remote service, database or some other source, you first need to know where that source is, then make a request to it and add it to your configuration. You are probably going to put the location of the remote configuration appsettings.json, then you call the remote config source.
Sounds easy? It is, but not obvious.

First, a little background.

In an out of the box Web API or MVC application you get a Program.cs that looks like this –

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

On line 9, we have WebHost.CreateDefaultBuilder(args), if you peek the definition of this with Resharper you will some something like –

The highlighted code is how your appsettings.json is loaded into the configuration and added to services collection, this call happens just as you leave Program.cs

But you want to read from the appsettings.json and use a value from it to make another call to get more configuration and then add the whole lot of the services collection. You might also want to setup some logging configuration in Program.cs, so you need access to all configuration settings before calling

CreateWebHostBuilder(args).Build().Run();

Here’s how you do it.

Step 1
Inside the main method in Program.cs, build the configuration yourself –

IConfigurationBuilder builder = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json");
Configuration = builder.Build();

Get the location of the other configuration service, in my example it is another json file.
Add it to the builder and call build.

string otherConfigService = Configuration["otherConfigService"]; // this could be a database or something like consul

builder.AddJsonFile(otherConfigService);
Configuration = builder.Build();

Now you have access to the configuration values from the second source.

Configuration["SomeOtherConfigItem1"]}
Configuration["SomeOtherConfigItem2"]}

So far so good, but as mentioned above, the CreateDefaultBuilder adds the configuration to the ServiceCollection, making it available by DI. But that only happens for appsettings.json (and appsettings.{env.EnvironmentName}.json, not the config you loaded from the other source.

If you tried to access the a config setting of your from inside Startup.cs or a controller, it would not be there.

Step 2
Let’s make our configuration available via the ServicesCollection.

In the first block of code above there was a call – CreateWebHostBuilder(args).Build().Run();

I added line 4 below, this will add the configuration to the services collection.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseConfiguration(Configuration); // add this line to add your configuration to the service collection

Now, the config values loaded from appsettings.json and your secondary config source will be available throughout your application.

Full source code available here.

Using Dependency Injection with Startup.cs in ASP.NET Core

Full source code available here.

Did you know that .NET Core 2 can pass in an instance of any type you want to the Startup.cs constructor? Well you can! Here’s how.

Out of the box the Startup.cs comes like this –

public class Startup
{
	public Startup(IConfiguration configuration)
	{
		Configuration = configuration;
	}
//snip..

The IConfiguration is passed in by dependency injection. In Program.cs you can add other types to the DI container, and then add that type to the constructor parameters of Startup.cs.

Here’s how it works. The Microsoft.AspNetCore.Hosting.WebHostBuilder has a ConfigureServices(...) method –

public IWebHostBuilder ConfigureServices(Action<IServiceCollection> configureServices)
{
    if (configureServices == null)
    {
        throw new ArgumentNullException(nameof(configureServices));
    }

    return ConfigureServices((_, services) => configureServices(services));
}

This lets you add services to the dependency injection container from the Program.cs.

WebHost.CreateDefaultBuilder(args) returns an IWebHostBuilder and that lets you use the ConfigureServices(...) method. Easy!

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureServices(serviceCollection =>
            serviceCollection.AddScoped<ISomeService, SomeService>())
        .UseStartup<Startup>()
        .Build();

And in Startup.cs

public class Startup
{
    private ISomeService _someService;
    public Startup(IConfiguration configuration, ISomeService someService)
    {
        _someService = someService;
        Configuration = configuration;
    }
// snip..	

The instance of ISomeService is of course available for DI everywhere in the application.

public class ValuesController : Controller
{
    private readonly ISomeService _someService;
    public ValuesController(ISomeService someService)
    {
        _someService = someService;
    }
}

Full source code available here.

Getting .NET Core 2.1 Preview 2 Working with Visual Studio 2017

About a year ago I wanted to start using .NET Framework 4.7, it should have been an easy process, but wasn’t. After some trial and error if figured it out and wrote a blog post explaining how to get it working.

Now with the release of .NET Core 2.1 Preview 2, I have hit the familiar problems – no obvious instructions from Microsoft, no one place to download all everything that needed and a Visual Studio install that does not include what you the latest SDK or runtime, and errors like – The specified framework 'Microsoft.AspNetCore.App', version '2.1.0-preview2-final' was not found. or, 'dotnet.exe' has exited with code -2147450730 (0x80008096).

After a few hours messing around and installing the wrong versions of the right software I figured it out.

Step 1

Install the latest version of Visual Studio Preview https://www.visualstudio.com/vs/preview/, at the time of writing this was version 15.7.0 Preview 4.0

I’m interested in developing Web API applications, so I check that box.

BUT, version 15.7.0 Preview 4.0 comes with .NET Core Version 2.1.0 Preview 1. So you don’t get the fancy new features like HttpClientFactory. Read on…

Step 2

Go to
https://github.com/dotnet/core/blob/master/release-notes/download-archives/2.1.0-preview2-download.md and download the SDK and the Runtime for your architecture.

You can verify the checksum of the downloads if you want to by comparing your SHA sum to these ones – https://dotnetcli.blob.core.windows.net/dotnet/checksums/2.1.300-preview2-008530-sdk-sha.txt

Install both the SDK and the runtime.

Step 3

To verify that that you are running .NET Core Preview 2, open visual studio and create a new .NET Core Web API application.

Once it has been created, open the .csproj file, you should see this block –

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0-preview2-final" />
</ItemGroup>

If you don’t see Version="2.1.0-preview2-final", something has gone wrong.

You can verify what packages are installed by going to your start menu and opening Apps and Features/Add or remove programs.

If you have installed the right SDK and runtime you should see the following –

The Circuit Breaker pattern with Polly

Full source code available here.

This post on the Polly circuit breaker is part of a larger series of post on the Polly Resilience Framework, see here for the others, or check out my Pluralsight course.

Basics
The circuit breaker controls the flow of requests from a source to one or more downstream system and cuts the connection when some failure condition is met and resumes the connection after a period. This lets us fail quickly when we know that some remote endpoint or host is not responding as we expect to requests. In this post I am only dealing with the basic circuit breaker, I’ll post another about the advanced circuit breaker later.

Benefits of a circuit breaker

  • Stops requests to the downstream system
  • Reduces load on a failing downstream system, giving it a chance to recover
  • The circuit breaker immediately returns an an error informing the source system that the circuit is open, the source system doesn’t have to wait for a timeout to occur
  • The application with the circuit breaker does not resource like memory, ports and threads when

Background and Terminology
The name, circuit breaker, comes from electrical circuit breakers in your home or office, in some countries these are referred to as trip switches. If the electrical system is working correctly, the circuit is closed and electricity flows to outlets and appliances. But if something goes wrong, the circuit opens, preventing electricity from flowing, thus protecting people and appliances.

The Polly circuit breaker has the corresponding closed and open positions. When closed, the circuit breaker allows requests to be sent, when open, nothing can be sent and an exception is immediately thrown if a request is send to the circuit breaker.

The Polly circuit breaker has one more status, half-open. When in this state Polly will allow the next request to be sent, and if it succeeds the circuit is closed (and normal operation resumes), but if it fails the circuit returns to open (preventing requests from being sent).
The circuit transitions from closed to open when the failure condition is met, from open to half-open when the specified break time is reached.

Here is the full set of possible transitions:
Closed to open – when the failure condition occurs
Open to half-open – when the duration of break is reached
Half-open to closed – when the first request is a success
Half-open to open – when the first request is a failure

The Policy
When creating a circuit breaker policy you specify the condition under which the circuit opens (breaks) and for how long. To be of any use the same instance of the policy must be used across multiple requests, so you cannot just instantiate it inside a controller.

This has implications, if you use the same circuit breaker policy when calling multiple downstream systems, if the circuit breaks for one, it breaks for all.
On the other hand, if you use a circuit breaker on just one downstream system, it can only break the circuit for that one.

I recommend passing policies into the controllers with dependency injection, in the example below I add the policy directly to the DI container, but you should consider using the Polly registry.

As mentioned above the circuit breaker opens when a specified failure condition is met. In the example policy the condition is two consecutive failure responses, the policy also specifies the duration of the break, in this case 10 seconds.

CircuitBreakerPolicy<HttpResponseMessage> breakerPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .CircuitBreakerAsync(2, TimeSpan.FromSeconds(10), OnBreak, OnReset, OnHalfOpen);

The policy is passed into the DI container this way –

In the controller, assign the circuit breaker to a local variable.

private readonly CircuitBreakerPolicy<HttpResponseMessage> _breakerPolicy;

public CatalogController(HttpClient httpClient, CircuitBreakerPolicy<HttpResponseMessage> breakerPolicy)
{
    _breakerPolicy = breakerPolicy;
    _httpClient = httpClient;
}

Then use it to make calls to the downstream systems, here –

[HttpGet("{catalogId}/inventory")]
public async Task<IActionResult> Get(int catalogId)
{
    string inventoryEndpoint = $"inventory/{catalogId}";

    HttpResponseMessage inventoryResponse = await _breakerPolicy.ExecuteAsync(
             () => _httpClient.GetAsync(inventoryEndpoint));

    //snip..
}

And here –

[HttpGet("{catalogId}/price")]
public async Task<IActionResult> GetPrice(int catalogId)
{
    string requestEndpoint = $"price/{catalogId}";

    HttpResponseMessage pricingResponse = await _breakerPolicy.ExecuteAsync(
            () => _httpClient.GetAsync(requestEndpoint));

    //snip..
}

Full source code available here.

How to install .NET Framework 4.7 in Visual Studio 2017

Microsoft just released .NET Framework 4.7, but surprisingly it is not the easiest to install.

Here are the steps for Windows 10, as of this writing, it is not available for earlier versions for of Windows.

1. Install Windows 10 Creators Update

Go here https://www.microsoft.com/en-us/software-download/windows10, download and install. This will take a while and will reboot your computer a few times.

2. Install Visual Studio 2017 Updates

In Visual Studio, go to Tools -> Extensions and Updates, install any available updates.

(You might have the option here to install 4.7, see the image below in step 4.)

3. Open Visual Studio 2017 Installer

Use the Start Menu to search for the Visual Studio Installer.

In the installer, click Modify on the version of Visual Studio you have installed.

4. Install .NET framework 4.7

Click .NET desktop development.

On the right select .NET Framework 4.7 and finally install.

A simple Polly example with WebApi 2

Download full source code.

If you are calling APIs and you haven’t heard about The Polly Project, you should check it out. It helps take care of many common problems like unreliable connections, retries and circuit breaking. It can also be used to wrap code where other forms of transient exception may occur.

In this blog post I’m going to show the wait and retry policy when calling an unreliable Web Api endpoint.

When using Polly there are two pieces that need you need to code – the policy and the execution of code wrapped by the policy.

In this example the policy is created in the constructor of the controller, this is NOT what you should do in a real application. For an example using DI to share policies see “Reusing Polly Policies with Dependency Injection”.

readonly RetryPolicy<HttpResponseMessage> _httpRequestPolicy;

public ValuesController()
{
    _httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>(
            r => r.StatusCode == HttpStatusCode.InternalServerError)
        .WaitAndRetryAsync(3,
            retryAttempt => TimeSpan.FromSeconds(retryAttempt));
}

This policy states that in the event that a HttpResponseMessage has a of InternalServerError, the request should be tried up to three times with a back off increasing by one second each time.

That’s the policy in place, now we need to call the web service endpoint.

public async Task<IHttpActionResult> Get()
{
   var httpClient = GetHttpClient();
   string requestEndpoint = "numbers/"; // numbers is the name of the controller being called

   HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(() => httpClient.GetAsync(requestEndpoint));

   IEnumerable<int> numbers = await httpResponse.Content.ReadAsAsync<IEnumerable<int>>();
   
   return Ok(numbers);
}

If you execute the code it makes a GET request to http://localhost:2351/api/values, despite two failures when calling the NumbersController you will get a 200 response and a list of numbers.

If you want to verify this, step through the provided solution with the debugger. You’ll see that the first two requests to the NumbersContoller return 500 errors and that the third succeeds and returns an array of ints.

With just a few lines of code Polly provided us with a robust wait and retry mechanism for web requests.

In another blog I’ll show a better way of defining policies so they can be used in any controller.

Download full source code.