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.

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.

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.

Registering Multiple Implementations of an Interface in ASP.NET Core with Autofac

Full source code here.

A few weeks ago I wrote a post about using dependency injection to pick between two implementations of an interface. It was a solution I was not very happy with because it meant I had to new up the implementations inside a factory or I had to use service collection to instantiate all implementations of the interface and then use a piece of code to return the one the was wanted.

As of this writing service collection does not natively support choosing between two implementations of a interface, but Autofac does and it can be used in place of service collection, or alongside it.

In this post I’m going to show its use alongside the service collection just for the dependencies that have multiple implementations, I’ll use service collection for dependencies that have a single collections. The examples are for ASP.NET Web Api Core 2.x and Core 3; there are small variations in how to use Autofac in those two versions of Core.

The Scenario
I have three controllers, the NegativeValuesController and PositiveValuesController take the same IValuesService and the third controller ProductsController takes an IProductsService.

The NegativeValuesController should get a NegativeValuesService and the PositiveValuesController should get a PositiveValuesService.

I’m going to use Autofac to provide the dependency injection for these controllers.

The ProductsController will use the built in ServiceCollection to fulfill its dependency.

Core 2.x
Start by adding the Autofac.Extensions.DependencyInjection package to the application.

Inside Program.cs add add .ConfigureServices(services => services.AddAutofac()) to the CreateWebHostBuilder statement.

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

In Startup.cs add this to the ConfigureServices(..) method –

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
	 .AddControllersAsServices(); // these two lines have to come before  
services.AddScoped<IProductsService, ProductsService>(); // you populte the builder a below

var builder = new ContainerBuilder();
builder.Populate(services);

builder.RegisterType<NegativeValuesService>().As<IValuesService>().AsSelf();
builder.RegisterType<PositiveValuesService>().As<IValuesService>().AsSelf();
builder.Register(ctx => new NegativeValuesController(ctx.Resolve<NegativeValuesService>()));
builder.Register(ctx => new PositiveValuesController(ctx.Resolve<PositiveValuesService>()));

AutofacContainer = builder.Build();

return new AutofacServiceProvider(AutofacContainer);

The controllers work in the normal, familar way –

public NegativeValuesController(IValuesService valuesService)
{
    _valuesService = valuesService;
}
public PositiveValuesController(IValuesService valuesService)
{
    _valuesService = valuesService;
}

That’s it, you can now choose the implementation you want for a controller.

Core 3
If you want to the same in Core 3, there are few small differences.

As before, start by adding the Autofac.Extensions.DependencyInjection package to the application.

In Program.cs add .UseServiceProviderFactory(new AutofacServiceProviderFactory()) to the CreateWebHostBuilder statement.

Back in Startup.cs add this method –

public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<NegativeValuesService>().As<IValuesService>().AsSelf();
    builder.RegisterType<PositiveValuesService>().As<IValuesService>().AsSelf();

    builder.Register(ctx => new NegativeValuesController(ctx.Resolve<NegativeValuesService>()));
    builder.Register(ctx => new PositiveValuesController(ctx.Resolve<PositiveValuesService>()));
}

Edit the ConfigureServices method to include the following –

public void ConfigureServices(IServiceCollection services)
{
	//snip..
	services.AddScoped<IProductsService, ProductsService>();

	services.AddControllers();
	services.AddMvc().AddControllersAsServices();
}

The usage inside the controllers does not change.

There you go, injecting multiple implementations of a interface in ASP.NET Core 2 and 3.

Full source code here.

Simmy Chaos Engine for .NET – Part 4, Doing Some Real Damage, Dropping a Table

Full source code here.

Up until now the Simmy examples I’ve written have thrown exceptions, changed successes to failures or slowed down a request. None of these did any real damage to your system, and your application would probably have recovered when the next request came along.

But what about dropping a table? Poof, all the data is gone. Now what does your application do?

Doing this is very easy with the Behavior clause. Like the other clauses it takes a probability, an enabled flag, and action or func that executes any piece of code.

The Scenario
I have Web API application with a products controller that queries the database for a list of products.

During application start up the database is created and populated in Configure method of Startup.cs using the EnsureCreated() method and custom seed class.

Inside the controller the action method uses the SalesContext to query the database.

Inside the controller’s constructor I have the chaos policy, it is set to drop the Products table. The drop action of the behavior policy will execute 25% of the time the policy is run. If get an error when you run this saying that the table is absent, it means the chaos policy dropped the table, you’ll have to restart the application to run through the database seeding and creation again.

The policy looks like this –

public ProductsController(SalesContext salesContext)
{
	_behaviorPolicy = MonkeyPolicy.InjectBehaviourAsync(
		 async () =>
		 {
			 await _salesContext.Database.ExecuteSqlCommandAsync("DROP TABLE Products");
			 Console.WriteLine("Dropped the Products table.");
		 },
		 0.25, // 25% of the time this policy will execute
		async () => await Task.FromResult(true));
	_salesContext = salesContext;
}

The request to the _salesContext is made inside the policy, but the policy executes before the call the db is made and in 25% of such calls the table will be dropped.

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

	return Ok(products);
}

You can of course execute and code from inside the policy, wipe a cache, kill a service, delete a file, etc.

This example might be a little excessive in the damage it does, you can decide if it is unreasonable to expect you application to continue working even when the database is unavailable.

Full source code here.

Registering Multiple Implementations of an Interface with Service Collection in ASP.NET Core

Full source code here.

This is a simplistic approach to the problem and assumes that the dependencies created by the factory do not in turn have their own dependencies. This deficiency could be mediated by passing those dependencies into the factory. Having said that it will be of use in some scenarios. I will publish a post in the future providing a better solution.

In a later post I will show how to use Autofac to do this properly.

The out-of-the-box dependency injection container provided by Microsoft as part of ASP.NET Core is fine for most scenarios, only in a few complicated cases have I needed to switch to Castle or AutoFac.

But there is one somewhat common case where the ServiceCollection feels a little deficient. There are times when you might have more than one implementation of an interface and you would like to choose between them at runtime.

There is no obvious way to do this.

You could try something like –

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IValuesService, PositiveValuesService>();
            services.AddScoped<IValuesService, NegativeValuesService>();
	//snip...

But when you request an implementation of IValuesService in the constructor of a controller, the service collection will return the last registered service, in this case it will always return the NegativeValuesService.

But what if you wanted the PositiveValuesService in some controllers and the NegativeValuesService in other controllers. What if you needed to choose the service implementation based on the address of the request that the controller is handling.

Something like this –
localhost:5000/NegativeValues – should use the NegativeValuesService.
localhost:5000/PositiveValues – should use the PositiveValuesService.

Using a Factory
Instead of registering two implementations of the IValuesService, I’m going to create a ValuesServiceFactory that returns the right service based on the path of the request.

The ValuesServiceFactory has a method that looks like this –

public IValuesService GetValuesService()
{
    string path = _httpContextAccessor.HttpContext.Request.Path.Value.ToString().Trim('/').ToLower();
    switch (path)
    {
        case "positivevalues":
            return new PositiveValuesService(); // as mentioned above this only works if the values services have no dependencies
        case "negativevalues":
            return new NegativeValuesService();
        default:
            return new PositiveValuesService();
    }
}

_httpContextAccessor is what lets me access the Request from inside the factory.

A few weeks ago I wrote about post about accessing the HttpRequest from inside the constructor of a controller or from the constructor of a service the controller depends on.

That post had a contrived example, but this post has a more practical use of the technique.

The constructor of the ValuesServiceFactory needs to take an IHttpContextAccessor.

public ValuesServiceFactory(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}

Back in Startup.cs, remove the code registering the two services and replace with a line to register the factory and the HttpContextAccessor.

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IValuesServiceFactory, ValuesServiceFactory>();
    services.AddHttpContextAccessor();
    //snip…
}

The controllers now take the implementation of IValuesServiceFactory and request the an IValuesService from the factory.

private readonly IValuesService _valuesService;

public NegativeValuesController(IValuesServiceFactory valuesServiceFactory)
{
    _valuesService = valuesServiceFactory.GetValuesService();
}

Do the same in the other controller –

private readonly IValuesService _valuesService;

public PositiveValuesController(IValuesServiceFactory valuesServiceFactory)
{
    _valuesService = valuesServiceFactory.GetValuesService();
}

That’s it, now you can choose between implementation of an interface. As I was working on this post I came across a post by Steve Gordon on this topic, he solves the same problem in a different way.

Full source code here.

Accessing the HttpContext from the Constructor of a Controller or a Dependency

Full source code here.

There are times when you may need to access the HttpRequest from places that it is not normally available such as the constructor of a controller or the constructor of a service that is built by dependency injection.

Take the example of a ValuesController that relies on a NumberGeneratorService, where both need to know the Host used in the request.

But you can’t just access the Host via the Request in either case. It is not yet available in the lifetime of the controller and it will not be available at all in the life of the service. (By the time you reach the action method of the controller you will have access to it.)

Fortunately there is a way to get at it using the HttpContextAccessor.

In Startup.cs add the following –

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<INumberGeneratorService, NumberGeneratorService>();
    services.AddHttpContextAccessor();
    //snip..
}

Pass IHttpContextAccessor to the constructor of the ValuesController

public ValuesController(IHttpContextAccessor httpContextAccessor, INumberGeneratorService numberGeneratorService)
{
    _numberGeneratorService = numberGeneratorService;
    Console.WriteLine($"Request.Host inside constructor of controller : {httpContextAccessor.HttpContext.Request.Host.Value}");
}

Do the same to the constructor of the the NumberGeneratorService

public NumberGeneratorService(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
    Console.WriteLine($"Request.Host inside service : {httpContextAccessor.HttpContext.Request.Host.Value}");
}

Now you have full access to everything about the request in controller’s constructor and the services you depend on.

In another post I’ll show a more practical use of this when I want to use the dependency injection with two implementations of an interface, HttpContextAccessor will help me choose between them based on the request.

Full source code here.

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.