AutoMapper, ProjectTo() – Instance Version

Full source code available here.

In my previous post I showed how to use the wonderful AutoMapper ProjectTo() feature, the demo code shown worked with AutoMapper up to v8.1.1. It looked like this –

_salesContext.Products.OrderBy(p => p.ProductId).Take(count).ProjectTo<ProductModel>()

But this will not work with AutoMapper v9 and above. You will be promptly informed that No overload for the method ‘ProjectTo’ takes 0 arguments.

What happend? Well, AutoMapper moved away from a static API to an instance only API.
To get this working you need to make a few minor changes compared to previous post.
In ConfigureServices(…) replace this –

Mapper.Initialize(cfg => {
    cfg.AddProfile<MappingProfile>();
});

With this –

services.AddAutoMapper(typeof(Startup));

Then in the controller, change this

public class ProductsController : ControllerBase
{
    private readonly SalesContext _salesContext;  

    public ProductsController (SalesContext salesContext)
    {
        _salesContext = salesContext;
    }
    // snip…

To this –

 
private readonly SalesContext _salesContext;
private readonly IMapper _mapper;

public ProductsController (SalesContext salesContext, IMapper mapper)
{
    _salesContext = salesContext;
    _mapper = mapper;
}
// snip..

And finally, the ProjectTo call changes from this –

[HttpGet("projected/{count}")]
public ActionResult GetProjected(int count)
{
    return Ok(_salesContext.Products.OrderBy(p => p.ProductId).Take(count).ProjectTo<ProductModel>());
}

To this –

[HttpGet("projected/{count}")]
public ActionResult GetProjected(int count)
{
    return Ok(_mapper.ProjectTo<ProductModel>(_salesContext.Products.Take(count).OrderBy(p => p.ProductId).Take(count)));
}

The SQL produced by the instance ProjectTo() is the same as what was produced by the static version.

That’s it, easy once you figure it out.

Full source code available here.

AutoMapper, ProjectTo() – Static Version

Full source code available here.

I’ve been using AutoMapper for quite a few years, but one of the features that I like the most is the ProjectTo method. When using Entity Framework it lets me reduce the number of fields I query from the database to match the model I want to return to the caller.
For example, I have a Product table in the database and a DTO that represents the Product that looks like this –

public class Product
{
	public int ProductId { get; set; }
	public string Name { get; set; }
	public ProductCategory ProductCategory { get; set; }
	public string Description { get; set; }
	public decimal Price { get; set; }
	public string SKU { get; set; }
	public string Code { get; set; }
}  

But say I wanted to return only the ProductId, Name and Code, I could run a query to return the full Product and the map the results to a model that looks like this –

public class ProductModel
{
	public int ProductId { get; set; }
	public string Name { get; set; }
	public string Code { get; set; }
}

In this scenario, the generated SELECT statement will request all seven fields in product and return them to the application, I then have to them to the ProductModel with the three fields I want.
Here is the SQL produced an executed –

SELECT TOP(@__p_0) [p].[ProductId], [p].[Code], [p].[Description], [p].[Name], [p].[Price], [p].[ProductCategory], [p].[SKU]
FROM [Products] AS [p]
ORDER BY [p].[ProductId]

Instead of requesting all seven fields the ProjectTo method will examine the model and generate only the SQL needed to return the relevant fields.

Here is the SQL produced –

SELECT TOP(@__p_0) [p].[Code], [p].[Name], [p].[ProductId]
FROM [Products] AS [p]
ORDER BY [p].[ProductId]

And here is how to write the C# code that performs this time saving, energy saving work –

var productModels = _salesContext.Products.OrderBy(p => p.ProductId).Take(count).ProjectTo<ProductModel>();

To get this to work you need to do some wiring up.
First add the nuget package AutoMapper.Extensions.Microsoft.DependencyInjection v6.1.1 to your project.

Then create a mapping profile, for this scenario it is very simple. The below code maps Product to ProductModel.

public class MappingProfile : Profile
{
	public MappingProfile()
	{
		CreateMap<Product, ProductModel>();
	}
}

In starup.cs add a call to Mapper.Initialize as shown here.

public void ConfigureServices(IServiceCollection services)
{
	Mapper.Initialize(cfg => {
		cfg.AddProfile<MappingProfile>();
	});

That’s all you need, but that’s not the end of the story…

This approach works with AutoMapper.Extensions.Microsoft.DependencyInjection up to v6.1.1, and AutoMapper v8.1.1, but if you move to newer versions you need a slightly different approach because the static API has been removed.

I’ll show that in the next blog post.

Full source code available here.

Simple Func<T> and Func<T1, T2, TResult> Examples

Full source code available here.

About a month ago I wrote a post with a simple explanation of how to use methods that take Action or Action<T> as parameters. Actions themselves take 0 to 16 parameters, and return nothing.

This is a follow up with some examples of how to call methods that take Func<TResult> or Func<T1, T2, TResult> as parameters. Funcs return a value and take 0 to 16 parameters.

As with Actions, there are a variety of ways to call methods that take Funcs.

Example 1

It’s not easy to come up with a non contrived examples for this post, and especially difficult for Func, a function that takes no parameters and returns something.

public static string DateCalculator(Func<double> daysSinceSomeDate)
{
   return $"{daysSinceSomeDate()} days in your date calculation";
}

This method expects a Func<double>, that is, a Func<TResult> that returns a double and takes no parameters.

Here are two examples calling this –

Console.WriteLine(DateCalculator(() => Math.Round(DateTime.Now.Subtract(new DateTime(2000,1,1)).TotalDays, 2)));
	
Console.WriteLine(DateCalculator(() => Math.Round(new DateTime(2020,12,31).Subtract(DateTime.Now).TotalDays , 2)));

The calls pass in a Func that performs a calculation with date subtraction, not very useful, as I said, it’s not easy to come up with a simple and useful example of using a Func<TResult>.

Example 2

This method expects a Func<int, int, int>, that is, a Func<T1, T2, TResult>. It takes two ints and returns an int.

public static void SomeMath(Func<int, int, int> mathFunction)
{
	int result = mathFunction(7, 5);
	Console.WriteLine($"The mathFunction returned {result}");
}

There are a variety of ways to call this. Here are some examples.

Create a method that takes two ints and returns an int.

public static int Subtraction(int number1, int number2)
{
	return number1 - number2;
}

You can now call SomeMath(..) like this –

SomeMath(Subtraction);

Or this –

Func<int, int, int> myFuncAsMethod = Subtraction;
SomeMath(myFuncAsMethod);

I like showing how you to pass a method into a method that takes a Func, because if you are ever struggling writing a lambda to satisfy a Func parameter, stop, and write a simple method instead to work out what you need to do. It can be easier to read, and is usually easier to debug.

Speaking of lambdas, here’s how to call the SomeMath(..) method with lambdas.

This is the simplest approach –

SomeMath((a, b) => a + b);

This lambda will take two parameters, named a and b, then performs addition on them. You can think of (a, b) as parameters to the “method body” to the right of =>. That “method body” adds a and b. There is also an implied “return” statement, but it can be left out of single line lambdas like that. For multi-line lambdas it is necessary.

Here is such an example –

SomeMath((x, y) =>
{
	int temp = x * y; // you can make your lambdas multi-line
	int calculatedNumber = temp * temp; 
	return calculatedNumber;
});

You can also assign a lambda to a declared Func, but I don’t see that done very often. You might do this if you are going to use the same lambda logic in multiple places.

Func<int, int, int> myFuncAsLambda = (a, b) => a * b;
SomeMath(myFuncAsLambda);

There are other ways to satisfy the method SomeMath(..), but these should be enough for most scenarios you will come across.

Full source code available here.

Streaming Results from Entity Framework Core and Web API Core – Part 2

Full source code available here.

Some time ago I wrote a post showing how to stream results from Entity Framework over Web API. This approach a few benefits – the results would not be materialized in the API code, a small amount of memory would be used irrespective of the size of the data returned, the results would being steaming as soon as possible and the speed of the request was faster than doing something like .ToList() or .ToListAsync().

In the example code I directly accessed the DbContext from the API controller, a reader of the blog got in touch to ask the database access code could be kept away from the API controller. This blog post shows a simple way of achieving this.

In the related post I had a method like this –

[HttpGet("streaming/")]
public IActionResult GetStreaming()
{
    IQueryable<Product> products = _salesContext.Products.AsNoTracking();
    return Ok(products);
}

The _salesContext was passed into the constructor of the ProductsController class using dependency injection and access directly.

In this post I’m going to pass a ProductsService into the ProductsController and use it to make the request to the database.

Here is how the controller now looks –

    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private readonly ProductsService _productsService;

        public ProductsController(ProductsService productsService)
        {
            _productsService = productsService;
        }

        [HttpGet("streamingFromService/{count}")]
        public ActionResult GetStreamingFromService(int count)
        {
            return Ok(_productsService.GetStreaming(count));
        }

        [HttpGet("streamingFromServiceWithProjection/{count}")]
        public ActionResult GetStreamingFromServiceWithProjection(int count)
        {
            return Ok(_productsService.GetStreamingWithProjection(count));
        }

        [HttpGet("nonStreamingFromService/{count}")]
        public async Task<ActionResult> GetNonStreamingFromService(int count)
        {
            return Ok(await _productsService.GetNonStreaming(count));
        }
    }

The ProductService is very simple, it makes the relevant calls to the database and returns the Products or ProductModels. For good measure I’ve added Automapper to project the Product to ProductModel, separating the underlying data type from the one presented to the caller.

    public class ProductsService
    {
        private readonly SalesContext _salesContext;
        private readonly IMapper _mapper;

        public ProductsService(SalesContext salesContext, IMapper mapper)
        {
            _salesContext = salesContext;
            _mapper = mapper;
        }

        public IQueryable<Product> GetStreaming(int count)
        {
            IQueryable<Product> products = _salesContext.Products.OrderBy(o => o.ProductId).Take(count).AsNoTracking();
            return products;
        }

        public IQueryable<ProductModel> GetStreamingWithProjection(int count)
        {
            var productModels = _mapper.ProjectTo<ProductModel>(_salesContext.Products.OrderBy(o => o.ProductId).Take(count).AsNoTracking());
            return productModels;
        }

        public async Task<IList<Product>> GetNonStreaming(int count)
        {
            IList<Product> products = await _salesContext.Products.OrderBy(o => o.ProductId).Take(count).ToListAsync();
            return products;
        }
    }

Now, some people might be concerned about returning an IQueryable, if you are see this post by Mark Seemann https://blog.ploeh.dk/2012/03/26/IQueryableTisTightCoupling/ to start digging into the topic.

While writing this I came across what seems like a severe performance bug in Entity Framework Core 3.x, I’m working on another post which will cover this is detail.

Full source code available here.

Simple Action and Action<string> Examples

Full source code available here.

A junior engineer colleague of mine recently asked me “how the f*** do I call this method?”. Seemed like a reasonable question. It was a method that took a complicated Func, and an Action with a series of parameters. We broke it down into each part and I explained them to him separately.

I think this is a problem that more people have so I going to try to give some simple examples that hopefully you can learn from and build on yourself.

This post will talk only about Actions, a later post will talk about Funcs. I’m not going to go into the details of delegates, anonymous methods, how they get called, when they get executed, etc, there are plenty of blog posts and articles out there on those topics already. Instead I’m going to focus on a few examples and explain them.

Example 1

This method takes an Action as a parameter, the Action itself has no parameters.

public static void Printer(Action myPrinterAction)
{
    myPrinterAction();
}

How do we call this? Here are few examples.
Create a second method –

public static void PrinterMethod()
{
    Console.WriteLine("Hello from PrinterMethod");
}

Now you can call Printer(..) like this –

Printer(PrinterMethod);

Or this

Printer(() => PrinterMethod());

To short cut this, you can use a lambda as the parameter to Printer(..). The lambda must take no arguments and return nothing, because that is how the Action the Printer method task is defined.

Printer(() => Console.WriteLine("Hello from Console.WriteLine"));

Generally, you will want to go for the lambda approach as it many people consider it the easiest to read.

There are more ways of calling Printer(..).
You can explicitly define an Action and assign the PrinterMethod to it.

Action printerActionAsMethod = PrinterMethod;
Printer(printerActionAsMethod);

You can explicitly define an Action and assign lambda to it.

Action printerActionAsLambda = () => Console.WriteLine("Explicitly defined printer action");
Printer(printerActionAsLambda);

There are other ways, but I think these are going to cover most of your needs.

Example 2

In this example the Printer method takes an Action as a parameter, this Action method takes a string as a parameter. The Printer(..) method also takes a string, this string is what the Action method will print.

public static void Printer(Action<string> myPrinterAction, string value)
{
    myPrinterAction(value);
}

How we call this is a little different than above. Here are few examples.
Create a second method –

public static void PrinterMethod(string text)
{
    Console.WriteLine($"Hello from PrinterMethod - {text}");
}

Then use it like this –

Printer(PrinterMethod, "Hi there");

Or this –

Printer((text) => PrinterMethod(text), "Calling print method");

Again, a lambda is probably the better approach. The lambda takes a single string as the argument and returns nothing, because that is how the Action the Printer(..) method task is defined.

Printer(someMessage => Console.WriteLine($"Hello from Console.WriteLine - {someMessage}"), "this is a lambda");

The included source code shows a few other ways of making the calls, but I think the ones discussed here will cover most of the scenarios you will hit.

Full source code available here.

Fluent Validation in ASP.NET Core 3.1

Full source code available here.

This is an update to a post I wrote in 2017 talking about Fluent Validation in ASP.NET Core.

The example is the same but there has been few updates. The first is how you setup the FluentValidation in Startup.cs, and the second is that you don’t need a ActionFilterAttribute anymore. I have included an example of how to call the action method using Fiddler.

Step 1

Firstly add the package to your Web Api project.
Install-Package FluentValidation.AspNetCore.
If you are going to keep your validators in the Web Api project that is all you need to add.

But if you put the validators in a different project you need to add the FluentValidation package to that project
Install-Package FluentValidation.

Step 2

In startup.cs add –

public void ConfigureServices(IServiceCollection services)
{
     services.AddControllers()
        .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<PersonModelValidator>());}
Step 3

Add a model and a validator.

public class PersonModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PersonModelValidator : AbstractValidator<PersonModel>
{
    public PersonModelValidator()
    {
        RuleFor(p => p.FirstName).NotEmpty();
        RuleFor(p => p.LastName).Length(5);
    }
}

Example Usage

In Fiddler, Postman or any other tool you POST to localhost:5000/person with the following header –

Content-Type: application/json

And body –

{
    "firstName": "",
    "lastName": "This is too long"
}

Here is how the request looks in Fiddler –

The response will look like this –

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|84df05e2-41e0d4841bb61293.",
    "errors": {
        "LastName": [
            "'Last Name' must be 5 characters in length. You entered 16 characters."
        ],
        "FirstName": [
            "'First Name' must not be empty."
        ]
    }
}

Easy to read that there are two errors.

Full source code available here.

POST with HttpClient and Basic Authorization

Full source code here.

A non .NET developer friend asked me to help him write a sample C# application that exercises a POST endpoint he wrote, it requires Basic authorization. After a quick search I found that there are relatively few good examples of doing this in .NET.

Step 1 – Authorization
The Basic authorization header that is added to request, is in the shape Authorization: Basic {authorization string}.

The {authorization string} is usually in the form of {username:password}, but it has to be base64 encoded. Go to https://www.base64encode.org/ and paste in something like –

aadams:kdshgs89g2qjaw09g

and you will get back

YWFkYW1zOmtkc2hnczg5ZzJxamF3MDln

That is your authorization string.

Step 2 – Getting the Json
I like using Fiddler, but you can use Postman, Insomnia or anything else you find too. Be careful with curl and Postman though, you don’t need to encode the authorization header with them, but you do with the likes of Fiddler and you must do it in the C# code.

For the purpose of this walkthrough I going to use this handy echoing endpoint https://postman-echo.com/post. You send it a request, it responds with the request you sent, request header details and other useful information.

When making a request to real API you will get the shape of the Json from the documentation for that API (and probably the response), but let’s pretend the documentation doesn’t include the response, or as often happens it is out of date.

Let’s say this is the Json to send –

{
    "firstName": "Andrew",
    "lastnName": "Adams",
     "age": 20
}

Use Fiddler to make the request –

The response you get back will look like –

{
    "args": {},
    "data": {
        "firstName": "Andrew",
        "lastnName": "Adams",
        "age": 20
    },
    "files": {},
    "form": {},
    "headers": {
        "x-forwarded-proto": "https",
        "host": "postman-echo.com",
        "content-length": "77",
        "authorization": "Basic YWFkYW1zOmtkc2hnczg5ZzJxamF3MDln",
        "content-type": "application/json",
        "user-agent": "Fiddler",
        "x-forwarded-port": "443"
    },
    "json": {
        "firstName": "Andrew",
        "lastnName": "Adams",
        "age": 20
    },
    "url": "https://postman-echo.com/post"
}

Great, you have the request and response.
Let’s start on the C#.

Step 3 – Convert Json to C#
This is easy thanks to tools like http://json2csharp.com/ and https://app.quicktype.io/.

Simply paste in the Json and it will produce the C# class or classes to represent the Json.

Depending on the Json serializer you are planning to use, you might need to make some adjustments to the C# produced, for example, if you want to use System.Text.Json you will need to change the attribute names from JsonProperty to JsonPropertyName.

Here is the PersonRequest class –

public class PersonRequest
{
	public PersonRequest(string firstName, string lastName, int age)
	{
		FirstName = firstName;
		LastName = lastName;
		Age = age;
	}
	[JsonPropertyName("firstName")]
	public string FirstName { get;  }

	[JsonPropertyName("lastnName")]
	public string LastName { get; }

	[JsonPropertyName("age")]
	public int Age { get;  }
}

This is the PersonResponse, there are classes to represent the other types (Data, Headers and Json) you can find them in the source code.

public class PersonResponse
{
	public override string ToString()
	{
		return $"Response includes \n \t {Data.ToString()} \n \t Auth header: {Headers.Authorization}";
	}

	[JsonPropertyName("data")]
	public Data Data { get; set; }

	[JsonPropertyName("headers")]
	public Headers Headers { get; set; }

	[JsonPropertyName("json")]
	public Data Json { get; set; }

	[JsonPropertyName("url")]
	public Uri Url { get; set; }
}

Step 4 – Encoding the Authorization String
This is a simple way to encode the string, but you could create an extension method to do the same –

public static string Base64Encode(string textToEncode)
{
      byte[] textAsBytes = Encoding.UTF8.GetBytes(textToEncode);
      return Convert.ToBase64String(textAsBytes);
}

Step 5 – Making the request, finally!
Add the Microsoft.AspNet.WebApi.Client nuget package to the project.

Now that all the plumbing is in place, it’s time to get the HttpClient to send the request.

HttpClient httpClient = new HttpClient
{
	BaseAddress = new Uri("https://postman-echo.com/")
};

httpClient.DefaultRequestHeaders.Add($"Authorization", $"Basic {Base64Encode($"{Username}:{Password}")}");

PersonRequest request = new PersonRequest("Andrew", "Adams", 99);

Make the request and deserialize the response as the PersonResponse

HttpResponseMessage httpResponseMessage = await httpClient.PostAsJsonAsync("/post", request).ConfigureAwait(false);
PersonResponse personResponse = await httpResponseMessage.Content.ReadAsAsync<PersonResponse>().ConfigureAwait(false);

There you go, not that easy if you are new to .NET.

Full source code here.

Simmy Chaos Engine for .NET – Part 7, Using a Random Chaos Policy

Full source code here.

This post builds on the previous one where I added chaos policies to a registry and dynamically configured their settings via a config file. In that example the chaos policy used was hard coded within the action method.

In this example the chaos policy will be chosen randomly from the available ones.

To accomplish this I have added an extension method to the Polly registry class. This method randomly chooses a chaos policy from the registry, you can find the source code from this in the attached file, it is not just a proof of concept and not designed to be robust.

Inside the controller the constructor remains the same as in the previous post.

public class BreweryController : Controller
{
	private readonly IHttpClientFactory _httpClientFactory;
	private readonly IPolicyRegistry<string> _policyRegistry;
	public BreweryController(IHttpClientFactory httpClientFactory, IPolicyRegistry<string> policyRegistry)
	{
		_policyRegistry = policyRegistry;
		_httpClientFactory = httpClientFactory;
	}

The action method then uses the registry extension method to choose a policy and make a request with the chaos policy.

var simmyPolicy = _policyRegistry.GetRandomChaosPolicy<AsyncMonkeyPolicy<HttpResponseMessage>>();
//snip..
var response =  await simmyPolicy.ExecuteAsync(async () => await httpClient.GetAsync(requestEndpoint));

If this is of use to you, you could consider adding another extension method to the registry to wrap multiple chaos policies together.

Full source code here.

Simmy Chaos Engine for .NET – Part 6, Configuring Policies Dynamically

Full source code here.

Simmy chaos policies have configurable options, via these options the polices can be turned on or off, have the rate at which they fire set, and in the case of the latency policy, the injected delay.

Here is an example of the fault policy –

AsyncInjectOutcomePolicy<HttpResponseMessage> faultPolicy = MonkeyPolicy.InjectFaultAsync<HttpResponseMessage>(
	new HttpRequestException("Simmy threw an exception, you should probably handle it in some way."),
	injectionRate: .5, //can be set through configuration
	enabled: () => true //can be set through configuration
);

And here is the latency policy –

var latencyPolicy = MonkeyPolicy.InjectLatencyAsync<HttpResponseMessage>(
	TimeSpan.FromSeconds(3), //can be set through configuration
	0.5, //can be set through configuration
	enabled: () => true); //can be set through configuration

This post shows how to set the all these settings via the appsettings.json file, but you could just as easily use a key store such as Consul or those provided by AWS and Azure. When you are using the application, change the values in appsettings.json and you will see the policies behave differently, try turning then on and off, changing the injection rate, and increasing/decreasing the delay.

In the appsettings.json I have something like –

{
  "SimmySettings": {
    "FaultPolicySettings": {
      "Enabled": false,
      "InjectionRate": 0.1
    },
    "LatencyPolicySettings": {
      "Enabled": true,
      "Latency": 3,
      "InjectionRate": 0.99
    }
  }
}

A matching FaultOptions.cs class.

namespace SimmyConfigurePolicies
{
    public class FaultOptions
    {
        public LatencyPolicySettings LatencyPolicySettings { get; set; }
        public FaultPolicySettings FaultPolicySettings { get; set; }
    }

    public class LatencyPolicySettings
    {
        public bool Enabled { get; set; }
        public double Latency { get; set; }
        public double InjectionRate { get; set; }

    }
    public class FaultPolicySettings
    {
        public bool Enabled { get; set; }
        public double InjectionRate { get; set; }
    }
}

The ConfigureServices method looks like this –

public void ConfigureServices(IServiceCollection services)
{
	services.AddOptions();

	services.Configure<FaultOptions>(Configuration.GetSection("SimmySettings"));
	services.AddPolicyRegistry();

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

	services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Note the services.AddOptions, Microsoft recommends adding this, but I have found it works fine without.
Also notice that I have NOT added any policies to the registry, if you have been following along with this series of blog posts you might have noticed that I usually add the policies inside ConfigureServices.

Instead I have moved the policies to the Configure method because I need to get at the instance of FaultOptions that is inside the service collection. There are ways to do this from inside ConfigureServices, but Microsoft warns you not to do this.
But accessing the FaultOptions from inside Configure is just fine. I define the policies and use the value inside the FaultOptions to configure the two policies.

For the fault policy I added a methods to make accessing the FaultOptions easier (you can see these in the attached source code), and for the latency policy I access the values directly.

Then add the policies to the registry.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
	_faultOptions = app.ApplicationServices.GetService<IOptionsMonitor<FaultOptions>>();

	AsyncInjectOutcomePolicy<HttpResponseMessage> faultPolicy = MonkeyPolicy.InjectFaultAsync<HttpResponseMessage>(
		FaultToThrow, // 
		FaultPolicyInjectionRate,
		FaultPolicyEnabled
	 );

	AsyncInjectLatencyPolicy<HttpResponseMessage> latencyPolicy = MonkeyPolicy.InjectLatencyAsync<HttpResponseMessage>(
		 TimeSpan.FromSeconds(_faultOptions.CurrentValue.LatencyPolicySettings.Latency),
		 _faultOptions.CurrentValue.LatencyPolicySettings.InjectionRate,
		 () => _faultOptions.CurrentValue.LatencyPolicySettings.Enabled);

	var registry = app.ApplicationServices.GetRequiredService<IPolicyRegistry<string>>();
	registry.Add("FaultPolicy", faultPolicy);
	registry.Add("LatencyPolicy", latencyPolicy);
	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
	}

	app.UseMvc();
}

The policies are used in the BreweryController, in the constructor I add the HttpClientFactory and the policy registry.
In the action method grab the policy from the registry and use it to make the request to the remote service.

public class BreweryController : Controller
{
	private readonly IHttpClientFactory _httpClientFactory;
	private readonly IPolicyRegistry<string> _policyRegistry;
	public BreweryController(IHttpClientFactory httpClientFactory, IPolicyRegistry<string> policyRegistry)
	{
		_policyRegistry = policyRegistry;
		_httpClientFactory = httpClientFactory;
	}

	public async Task<IActionResult> Get(string state = "Massachusetts", string name = "night shift brewing")
	{
		var simmyPolicy = _policyRegistry.Get<AsyncMonkeyPolicy<HttpResponseMessage>>("LatencyPolicy");
		//var simmyPolicy = _policyRegistry.Get<AsyncMonkeyPolicy<HttpResponseMessage>>("FaultPolicy");
		string requestEndpoint = $"?by_state={state}&by_name={name}";

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

		var response =  await simmyPolicy.ExecuteAsync( async () => await httpClient.GetAsync(requestEndpoint));
		if (response.IsSuccessStatusCode)
		{
			var breweries = await response.Content.ReadAsAsync<List<Brewery>>();
			return Ok(breweries);
		}

		return StatusCode((int)response.StatusCode, await response.Content.ReadAsStringAsync());
	}
}

There are a few improvements that can be made to this and I’ll show them over the next few posts, one is to select a random chaos policy from the registry and the second is to apply the chaos policies to HttpClientFactory policy selector.

Full source code here.

Passing Configuration Options Into Middleware, Services and Controllers in ASP.NET Core 3.1

Full source code here.

I recently hit a problem where I needed to reload configuration settings as they changed, fortunately this is relatively straightforward when using the IOptionsMonitor, in .NET Core.

Add a few lines to ConfigureServices, pass the configuration options as a scoped service to the controller or into another service and everything works.

Here is all you need in the ConfigureServices method –

public void ConfigureServices(IServiceCollection services)
{
	services.AddOptions();
	services.Configure<WeatherOptions>(Configuration.GetSection("WeatherOptions"));
	services.AddScoped<ISomeService, SomeService>();

Here’s the service that takes the IOptionsMonitor

public class SomeService : ISomeService
{
	private readonly WeatherOptions _weatherOptions;

	public SomeService(IOptionsMonitor<WeatherOptions> weatherOptions)
	{
		_weatherOptions = weatherOptions.CurrentValue;
	}
// snip..

And here is the controller taking the IOptionsMonitor and the service that also uses the options, this is of course contrived and you almost certainly would not want to take both constructor parameters –

public class WeatherForecastController : ControllerBase
{
	private readonly WeatherOptions _weatherOptions;
	private readonly ISomeService _someService;
	public WeatherForecastController(IOptionsMonitor<WeatherOptions> weatherOptions, ISomeService someService)
	{
		_someService = someService;
		_weatherOptions = weatherOptions.CurrentValue;
	}

But what if you also had to pass those configuration settings into a piece of middleware that executes on each request and if they configuration values change you want to be reflected in the execution of the middleware. This is not so easy because the constructor of a middleware class can only have singletons injected into it, same applies to the Configure method Startup.

Fortunately, the Invoke method can have a scoped service injected into it, see here for more.

public class SomeMiddleware
{
	private readonly RequestDelegate _next;

	public SomeMiddleware(RequestDelegate next)
	{
		_next = next;
	}

	public async Task InvokeAsync(HttpContext context, ISomeService someService)
	{
		someService.DoSomething("Middleware - ");
		await _next(context);
	}
}

To use the middleware, add a single line to the Configure method –

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	app.UseMiddleware<SomeMiddleware>();
	//snip..

That’s it.

Full source code here.