Simmy Chaos Engine for .NET – Part 2, Resilience and Injected Faults

Full source code here.

I wrote a blog on using a Simmy Fault policy a few days ago, it is very simple to use by itself, but it is far more useful when used in combination with a resilience policy.

Take the scenario where I have added retry logic to my requests, but the requests never fail, how do I know the retry logic works the way I expect. This is where the fault policy shines.

I’m going to build on the previous post where I injected a fault 50 percent of the time when making http requests. In the previous post I had Simmy throw a HttpRequestException but this time I’m going to have Simmy return a HttpResponseMessage containing an InternalServerError.

Along with the fault policy, I am going add a simple retry policy, retrying up to three times.

Here’s how it will work –

The fault policy executes –

If the fault policy is active and a fault is to be returned (remember this happens 50% of the time) a InternalServerError is returned. The HttpClient does NOT make a request to the remote service

The retry policy executes. The handles clause sees the InternalServerError and the behavior clause of the retry kicks in and performs the retry

The fault policy executes again

The preceding two steps repeat until a request succeeds or the retry policy reaches is limit of 3 retries

 

If the fault policy is not active, or a fault is NOT to be returned

the HTTP client executes the request to the remote service

the handles clause of the retry determines whether a retry should be performed

 

This is what it looks like –

At the center is the HttpReqeust, around it is the fault policy and around everything is the retry policy.

To achieve all this in code is very simple, in ConfigureServices add the fault policy.

public void ConfigureServices(IServiceCollection services)
{
	HttpResponseMessage faultHttpResponseMessage = new HttpResponseMessage(HttpStatusCode.InternalServerError)
	{
		Content = new StringContent("Simmy swapped the Ok for an Internal Server Error")
	};
	AsyncInjectOutcomePolicy<HttpResponseMessage> faultPolicy = MonkeyPolicy.InjectFaultAsync(
		faultHttpResponseMessage,
		injectionRate: .5,
		enabled: () => true 
	);

When the fault policy executes, 50% of the time it will return an InternalServerError response, preempting the real request to the remote service.

Next is the retry policy, its behavior clause triggers if the HttpResponseMessage is not a success.

IAsyncPolicy<HttpResponseMessage> retryPolicy = Policy
	.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
	.RetryAsync(3, onRetry: (message, retryCount) =>
	{
		Console.WriteLine($"Retry: {retryCount}");
	});

Wrap the retry policy around the fault policy.

AsyncPolicyWrap<HttpResponseMessage> faultAndRetryWrap = Policy.WrapAsync(retryPolicy, faultPolicy);

Finally, create the HttpClientFactory, passing in the policy wrap. If you are not familiar with how the HttpClientFactory works read Steve Gordon’s series or my blog posts on it. If you want know how it works with Polly, take a look at my posts on that topic.

services.AddHttpClient("OpenBreweryDb", client =>
{
	client.BaseAddress = new Uri("https://api.openbrewerydb.org/breweries/");
	client.DefaultRequestHeaders.Add("Accept", "application/json");
}).AddPolicyHandler(faultAndRetryWrap);

To fire of the HttpClient request inside the BreweryController remains the same –

string requestEndpoint = $"?by_state={state}&by_name={name}";
var httpClient = _httpClientFactory.CreateClient("OpenBreweryDb");
var response = await httpClient.GetAsync(requestEndpoint);

Full source code here.

Streaming Results from Entity Framework Core and Web API Core

Full source code here.
The code provided will not compile until you make a change in seeder.cs, the way it’s written it generates 500,000 rows in a local db. Set this to whatever value you want.

In this post I’m going to show you how to return an unlimited number of results from a database via a Web API application while keeping your memory usage low and constant. In effect, you are going to stream results from the database with Entity Framework.

To achieve this you need to do two things, disable tracking and return a not materialize your data inside the action method.

Turn off tracking
By default Entity Framework tracks entities that you read from a database. Tracking allows EF to determine what, if any, properties have changed since being loaded, then EF can save just the relevant changes. But tracking takes up memory and CPU.

If you have no intention of changing these entities there is no point in tracking them.

There are two ways of doing this, at point where you make the request to the database, or globally for the whole context.

To use AsNoTracking for a single request it looks like this –
_salesContext.Products.AsNoTracking().Where(..)

To use it for all requests to that context set AsNoTracking in the constructor of the context.

public SalesContext(DbContextOptions<SalesContext> options) : base(options)
{
	ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}

That’s the first step taken care of, now we make sure not to turn our data into objects inside the controller.

Do not materialize
If you follow tutorials on Entity Framework Core and Web API you will see examples like this –

[HttpGet]
public async Task<ActionResult> Get()
{
    List<Product> products = await _salesContext.Products.ToListAsync();

    return Ok(products);
}

In this example, all the products in the database are read and put into a list of products, the return does not execute until after all the data has been read, so you are waiting for this to complete before getting any results. You are also storing the whole list of products in memory (you are probably also tracking the entities).

Instead of that you can do the following –

[HttpGet]
public ActionResult GetStreaming()
{
	IQueryable<Product> products = _salesContext.Products.AsNoTracking();

	return Ok(products);
}

Now, the products do not materialize, there is no list to store in memory, tracking is turned off and the action method begins returning data almost immediately.

Your memory profile will be almost same whether you are returning a few hundred or a few million rows of data.

Example of Memory Usage
Below are screenshots from Visual Studio 2017 of the application running showing the amount of memory consumed for a variety of requests. The first shows the memory usage when I requested a single row from the database

The following images show the memory usage when streaming and not streaming results sets of 100,000, 200,000, 300,000 and 500,000.

106 MB used for a single row

 

100,000 rows returned. On the left is with streaming, on the right without.

 

200,000 rows returned. On the left is with streaming, on the right without.

 

300,000 rows returned. On the left is with streaming, on the right without.

 

500,000 rows returned. On the left is with streaming, on the right without.

 

Summary of Results

It’s obvious that streaming maintains a uniform memory footprint while the memory consumed for non-streaming grows with the number of rows returned.

What you don’t see here is that streaming requests complete more quickly. If you download the attached code and use a local mdf file, you probably won’t see much of a difference in speed, but if your application connects to remote database you will see approximately a 20% improvement in speed.

Summary
For streaming to work you need to turn of tracking of entities and return an IQueryable from the action method.

Full source code here.
The code provided will not compile until you make a change in seeder.cs, the way it’s written it generates 500,000 rows in a local db. Set this to whatever value you want.

Getting Error Messages and Status Codes from Typed HttpClients

Full source code here.

I have been using HttpClientFactory for a while and have generally preferred using named clients over typed clients. With a named client you get the HttpClient just before you are going to use it, and you have full access to the HttpResponse at the point you make the call to the remote service.

var httpClient = _httpClientFactory.CreateClient("InvoiceApi");
HttpResponseMessage response = await httpClient.GetAsync(requestEndpoint);

This is great when things go wrong because you can check the HttpStatus code and the ReasonPhrase, any message, and then take appropriate action.

If you are using a typed client, it might look something like this –

public class InvoiceClient
{
	private readonly HttpClient _client;

	public InvoiceClient(HttpClient client)
	{
		_client = client;
	}
	
	public async Task<Invoice> GetInvoice(int orderId)
	{
		var response = await _client.GetAsync($"invoice/{orderId}");
		Invoice invoice = await response.Content.ReadAsAsync<Invoice>();
		return invoice;
	}
}

And then you use it –

var invoice = await invoiceClient.GetOrder(id);

If the request worked, you are fine, but if it didn’t you and got an error, then the deseriaization will fail and an exception will be thrown, but that exception won’t tell you very much about the cause of the original failure.

Returning a typed response
Here’s the alternative. I use a typed response that includes the HttpStatusCode, the ReasonPhrase and the content I actually want, in this case the Invoice.

public class TypedResponse<T>
{
	public T Content { get; set; }
	public HttpStatusCode HttpStatusCode { get; set; }
	public string ReasonPhrase { get; set; }
	public string Message { get; set; }
}

Here’s how to change the Get method in the Invoice.

[HttpGet("{orderId}")]
public async Task<ActionResult> Get(int orderId)
{
	// Pretend to load the order from the db. 
	Order order = new Order { OrderId = orderId, OrderDate = new DateTime(2018, 6, 14), CustomerId = 1001 };

	var invoiceResponse = await _invoiceClient.GetInvoice(orderId);

	if (invoiceResponse.Content != null)
	{
		order.Cost = invoiceResponse.Content.Cost;
		return Ok(order);
	}
	return StatusCode((int)invoiceResponse.HttpStatusCode, invoiceResponse.Message);
}

And finally, how to use it in the controller.

var invoiceAndStatus = await _invoiceClient.GetInvoice(orderId);

if (invoiceAndStatus.Content != null)
{
    order.Cost = invoiceAndStatus.Content.Cost;
    return Ok(order);
}
return StatusCode((int)invoiceAndStatus.HttpStatusCode, invoiceAndStatus.Message);

Run the code, it will open your browser to http://localhost:5000/api/order/2. The OrderController will call the InvoiceController, the first request will fail, but you will see the error message from the InvoiceController.

Hit F5 in the browser to make another request to the OrderController, again this calls the InvoiceController, but this time the response is a success.

Full source code here.

Selectively Caching a HttpResponseMessage with Polly – caching series 1/3

Full source code here.

When I give talks on Polly I show how to use it in a Web API application that calls another Web Api application. I give a simple example of how to use the cache policy where I store the whole of the HttpResponseMessage. At the end of the talk I often get a couple of questions –

1. is it possible to cache the response only when the status code is in the 200 range.
2. is it possible to cache the values inside the response instead of the whole response.

The answer to both of these is yes, and in this series of three articles I will explain how to do both of these things, and how how to combine them to cache a value inside a response only if the response is in the 200 range.

This article will demonstrate how to selectively cache HttpResponseMessages based on the Http StatusCode of the response.

As described in an earlier post, using a cache policy is a little more involved than using other policies. See this post for more info.

Changes in Startup
In Startup inside ConfigureServices I setup the memory cache, the HttpClientFactory and a policy registry (I’m not going to go into a detailed explanation of this code as it is already explained in the earlier article and you have all the source code).

All the action for this post takes place in the Configure method.

Creating the cache filter
The cache timeout filter, it sets the length of time to cache a value. The filter here will cache a response for 10 seconds if the response indicates a success, otherwise it caches the response for 0 seconds, in this case the Polly code does not perform any caching.

public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    IAsyncCacheProvider cacheProvider, IPolicyRegistry<string> registry)
{
    Func<Context, HttpResponseMessage, Ttl> cacheOnly200OkFilter =
        (context, result) => new Ttl(
            timeSpan: result.StatusCode == HttpStatusCode.OK ? TimeSpan.
            slidingExpiration: true
        );

The cache policy says that it caches HttpResponseMessages and uses the filter to decide if a response should be cached.

IAsyncPolicy<HttpResponseMessage> cacheOnlyOkResponsePolicy =
    Policy.CacheAsync<HttpResponseMessage>(
        cacheProvider.AsyncFor<HttpResponseMessage>(), //note the .AsyncFor<HttpResponseMessage>
        new ResultTtl<HttpResponseMessage>(cacheOnly200OkFilter),
        onCacheError: null
    );

Note the AsyncFor, this is very important. Thanks to Dylan Reisenberger for his help here, I spent too many hours trying to figure the overloads with no success.

Try it out in the provided solution, hit F5 and put some breakpoints in the controllers and on the filter in Startup.

That’s it, you now have selective caching of responses.

In the next post, I’ll show you how to cache the value inside the response instead of the whole response.

Full source code here.

Calling Generic Methods Using Reflection

Full source code here.

Accessing generic methods by reflection is not easy. A while ago I needed to do just that and found relatively little information out there. So I dug in a figured it out for myself.

Here are some of the possible ways that you could execute generic methods by reflection –

  • Execute a Generic Instance Method in a Non-Generic Class
  • Execute Generic Static Method In a Non-Generic Class
  • Execute Generic Overloaded Static Method
  • Execute NonGeneric Method in a Generic Class

There are other variations, but you should be able to figure out how to write them based on the ones shown here.

In the classes PrinterA and PrinterB, there are a variety of generic and one non-generic methods that I will call using reflection from Program.

The code will explain things better than I can, so here is the listing.

using System;
using System.Collections.Generic;

namespace ExecuteGenericMethodByReflection
{
    public class PrinterA<T>
    {
        public void Print(IEnumerable<T> items)
        {
            Console.WriteLine();
            foreach (var item in items)
            {
                Console.Write($"{item} ");
            }
        }
    }
}
using System;
using System.Collections.Generic;

namespace ExecuteGenericMethodByReflection
{
    public class PrinterB
    {
        public void PrintSimple<T>(IEnumerable<T> items)
        {
            Console.WriteLine();

            foreach (var item in items)
            {
                Console.Write($"{item} ");
            }
            Console.WriteLine();

        }

        public static void PrintPrefixAndSuffix<T>(IEnumerable<T> items, string prefix, string suffix)
        {
            Console.Write(prefix);
            foreach (var item in items)
            {
                Console.Write($" {item} ");
            }
            Console.Write(suffix);
            Console.WriteLine();
        }

        //This and the next method are overloads
        public static void PrintPrefix<T>(IEnumerable<T> items, string prefix)
        {
            Console.Write(prefix);

            foreach (var item in items)
            {
                Console.Write($" {item}");
            }
            Console.WriteLine();

        }

        public static void PrintPrefix<T>(IEnumerable<T> items, int prefix)
        {
            Console.WriteLine(prefix);

            foreach (var item in items)
            {
                Console.Write($" {item}");
            }
            Console.WriteLine();
        }

    }
}

And here is program where all the crazy reflection takes place.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace ExecuteGenericMethodByReflection
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();

            List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };

            p.ExecuteGenericInstanceMethodInNonGenericClass(numbers);
            p.ExecuteGenericStaticMethodInNonGenericClass(numbers);
            p.ExecuteGenericOverloadedStaticMethod(numbers);

            p.ExecuteNonGenericMethodInGenericClass(numbers);

            Console.WriteLine("\n\nPress any key to exit...");
            Console.ReadKey();
        }

        private void ExecuteGenericInstanceMethodInNonGenericClass(object objectToPrint)
        {
            Type typeToPrint = objectToPrint.GetType().GetGenericArguments()[0];

            PrinterB genericPrinter = new PrinterB();
            MethodInfo printSimpleMethod = typeof(PrinterB).GetMethod("PrintSimple");
            MethodInfo printSimpleMethodToExecute = printSimpleMethod.MakeGenericMethod(typeToPrint);

            printSimpleMethodToExecute.Invoke(genericPrinter, new object[] { objectToPrint});
        }

        private void ExecuteGenericStaticMethodInNonGenericClass(object objectToPrint)
        {
            Type typeToPrint = objectToPrint.GetType().GetGenericArguments()[0];
            MethodInfo printPrefixAndSuffixMethod = typeof(PrinterB).GetMethod("PrintPrefixAndSuffix");
            MethodInfo genericprintPrefixAndSuffixMethodToExecute = printPrefixAndSuffixMethod.MakeGenericMethod(typeToPrint);

            genericprintPrefixAndSuffixMethodToExecute.Invoke(null, new object[] { objectToPrint, "My Prefix", "My Suffix" });
        }

        // Executing an overloaded method is more diffcult, the method has to be identified by its parameters
        private void ExecuteGenericOverloadedStaticMethod(object objectToPrint)
        {
            string prefixToPrint = "My Prefix";
            Type overloadType = prefixToPrint.GetType();
            Type typeToPrint = objectToPrint.GetType().GetGenericArguments()[0];
            MethodInfo genricMethodToExecute = GetOverloadedMethod(typeToPrint, overloadType);
            genricMethodToExecute.Invoke(null, new object[] { objectToPrint, prefixToPrint });
        }

        private void ExecuteNonGenericMethodInGenericClass(object objectToPrint)
        {
            Type typeToPrint = objectToPrint.GetType().GetGenericArguments()[0];

            Type printerAType = typeof(PrinterA<>);
            Type genericPrinterAType = printerAType.MakeGenericType(typeToPrint);

            object genericPrinterAInstance = Activator.CreateInstance(genericPrinterAType);
            MethodInfo printMethod = genericPrinterAType.GetMethod("Print");
            printMethod.Invoke(genericPrinterAInstance, new object[] { objectToPrint });
        }

        private MethodInfo GetOverloadedMethod(Type typeToPassToGenericMethod, Type overloadType)
        {
            IEnumerable<MethodInfo> printMethods = typeof(PrinterB).GetMethods().Where(m => m.Name == "PrintPrefix");
            MethodInfo printMethod = printMethods.Single(m => m.GetParameters().Any(p => p.ParameterType == overloadType));
            MethodInfo genericPrintMethod = printMethod.MakeGenericMethod(typeToPassToGenericMethod);
            return genericPrintMethod;
        }
    }
}

Full source code here.

Dynamically Updating the Request Header of a HttpClientFactory Generated HttpClient, Part 1

Full source code here.

There are some subtle issues in the way I use DI in this post, see here for an alternative if you don’t want to follow this approach

While using the HttpClientFactory I hit a scenario where I needed to update the value of a token passed in the header of requests, the token changed frequently, so I had to repeatedly update it throughout the lifetime of my application.

You have a couple of options for this, the first is to do it after you have taken a HttpClient from the factory at the point where you make your outbound request, this is straightforward, but now everywhere use a HttpClient you have to be able to get a new token. For some this might be fine, and you can use –

    httpClient.DefaultRequestHeaders.Add("Token", _tokenGenerator.GetToken());

Doing it with HttpClientFactory
The better approach is to put all this logic in the Startup.cs and update the header when the factory returns a new HttpClient, now everywhere you use the HttpClient gets the updated token without any work for you.

In my example case I have a token generator and memory cache. If there is a token in the cache, that one is used, if not the token generator generates and stores the new token in the cache for specified period.

In my Startup.cs all I need is this –

services.AddHttpClient("RemoteServer", client =>
{
    client.BaseAddress = new Uri("http://localhost:5000/api/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
    client.DefaultRequestHeaders.Add("Token", TokenGenerator.GetToken());
});

Read on to see how to wire everything up.

A little known feature of .NET Core is the ability to DI from Program.cs into Startup.cs, I have written about this before in Using Dependency Injection with Startup.cs in ASP.NET Core and am using it again here.

In Program.cs I add a memory cache and a token generator to the service collection.

Adding to the service collection this way can have some unexpected side effects, check this post for an alternative approach.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureServices(cs => cs.AddMemoryCache())
    .ConfigureServices(cs => cs.AddSingleton<ITokenGenerator, TokenGenerator>())
        .UseStartup<Startup>();

In Startup.cs I pass a ITokenGenerator to the constructor.

public Startup(IConfiguration configuration, ITokenGenerator tokenGenerator)
{
    Configuration = configuration;
    TokenGenerator = tokenGenerator;
    string token = tokenGenerator.GetToken(); // do something with the token
}

private ITokenGenerator TokenGenerator { get; }
// snip

Then a simple call the TokenGenerator.GetToken() updates the header of the client the factory returns to callers.

For completeness, here is the implementation of the TokenGenerator.cs

public class TokenGenerator : ITokenGenerator
{
    private readonly IMemoryCache _memoryCache;
    public TokenGenerator(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }

    public string GetToken()
    {
        string token;
        if (_memoryCache.TryGetValue("Token", out token))
        {
            return token;
        }
        else
        {
            // here you would have a more realistic way of generating a new token
            token = Guid.NewGuid().ToString();
            _memoryCache.Set("Token", token, TimeSpan.FromSeconds(10));

            return token;
        }
    }
}

Full source code here.

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’s 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.