Getting Started with ElasticSearch, Part 1 – Seeding

Full source code available here.

This is the first in a short series of blog posts that will get you started with ElasticSearch. In this you will deploy seed and query ElasticSearch from your own computer. The next will add a .NET Core API into the mix as a ‘frontend’ for ElasticSearch. And the last will show how to deploy an ElasticSearch domain on AWS using an infrastructure as code tool.

This post will show you how to create a simple document mapping, seed the ElasticSearch index and perform some simple queries. It is not a substitute for reading the docs, it is more of step up to help you get going.

Getting Started
Download and install the latest version of ElasticSearch, this post was written when 7.7 was the up to date version, I mention this because if you are reading this when a version > 7 is available the steps may not work – ElasticSearch is known for making major breaking changes in major releases.

Start up ElasticSearch by changing to its directory and running –

bin/elasticsearch

It will start on localhost:9200 by default.

If you are using Visual Studio Code I suggest installing the Rest Client extension. The elasticSearch.http file in attached zip contains examples of how to create and delete indexes, add mappings, and perform queries.

At the top of my elasticSearch.http I have two variables that will be used throughout the rest of the file, these define the host where ElasticSearch is running and the name of the index I’m working with

@elasticSearchHost = http://localhost:9200
@index = customers

To see the indexes that are already in place run this –

GET {{elasticSearchHost}}/_cat/indices?v&pretty

Adding an Index with Rest Client

Let’s add the customer index with Visual Studio Rest Client, of course you can use Postman, Fiddler or any tool of your choosing –

PUT {{elasticSearchHost}}/{{index}}
Content-Type: application/json

{
  "mappings": {
    "properties": {
      "companyName": {
        "type": "text"
      },
      "customerId": {
        "type": "integer"
      },
      "dateOfBirth": {
        "type": "date"
      },
      "email": {
        "type": "text"
      },
      "firstName": {
        "type": "text",
        "copy_to": "fullName"
      },
      "middleName": {
        "type": "text",
        "copy_to": "fullName"
      },
      "lastName": {
        "type": "text",
        "copy_to": "fullName"
      },
      "fullName": {
        "type": "text"
      },      
      "mobileNumber": {
        "type": "text"
      },
      "officeNumber": {
        "type": "text"
      },
      "address": {
        "properties": {
          "line1": {
            "type": "text",
            "copy_to": "fullAddress"
          },
          "line2": {
            "type": "text",
            "copy_to": "fullAddress"
          },
          "city": {
            "type": "text",
            "copy_to": "fullAddress"
          },
          "state": {
            "type": "text",
            "copy_to": "fullAddress"
          },
          "zip": {
            "type": "text",
            "copy_to": "fullAddress"
          }
        }
      },
      "fullAddress": {
          "type": "text"
      }
    }
  }
}

Run the request to list indexes again and you will see the customers index.

GET {{elasticSearchHost}}/_cat/indices?v&pretty

Now you have an index full of nothing, docs.count is 0 –

health status index     uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   customers RDWD3Q75TVqf7VkvO932mA   1   1          0            0       208b           208b

Seeding
Time to switch to the seeder. This is Node.js program that checks if the customers index exists, creates it if it does not, and seeds the index with 5000 customer documents.

I’m not going to go into how it works as I am learning Node.js now and I’m sure it is not as good as it should be. You can execute it by running –

npm install
node seed.js

Now you should see a different result when you look at the indexes on the ElasticSearch server.

GET {{elasticSearchHost}}/_cat/indices?v&pretty

health status index     uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   customers wsdQcJ1IQNOXQ-QQIX_a_Q   1   1       5000            0      2.4mb          2.4mb

Here are a few examples of requests you can make to ElasticSearch.

###
# delete an index, BE CAREFUL WITH THIS ONE
DELETE {{elasticSearchHost}}/{{index}}?pretty

###
# retrieve a document from the index by its id
GET {{elasticSearchHost}}/{{index}}/_doc/1

###
# search the index with no query, this will match all documents, but return only the first few
GET {{elasticSearchHost}}/{{index}}/_search

###
# retrieve a page of results with no query
GET {{elasticSearchHost}}/{{index}}/_search
Content-Type: application/json

{
  "sort":{"dateOfBirth": {"order":"asc"}},
  "from": 0,
  "size": 10
}

###
# search for company names that match the word 'Turcotte', you might need to change this name
GET {{elasticSearchHost}}/{{index}}/_search
Content-Type: application/json

{
    "query": {
        "match_phrase_prefix": {
            "companyName" : "Turcotte" 
        } 
    }
}

###
# search for people in Utah with the name Keith (first, middle or last), you might need to change these parmas.
GET {{elasticSearchHost}}/{{index}}/_search
Content-Type: application/json

{
    "query": {
        "bool": {
            "must": [
                {"match_phrase_prefix": { "fullName" : "Keith" } }
               ,{"match": { "address.state" : "Utah"}} 
            ]
        }
    }
}

That’s it for now.

In the next blog post I will show you how to use `HttpClientFactory` and typed clients to perform searches in .NET Core.

Full source code available here.

Dependency Inject a Service from Startup back to Program in .Net Core 3.1

Full source code available here.

Over the past couple of years I wrote a few posts about Dependency Injection in .Net Core 2.1, and this week I received comments from a reader telling me that some of the changes in .Net Core 3.1 mean that some of the approaches no longer work. There have been breaking changes https://docs.microsoft.com/en-us/dotnet/core/compatibility/2.2-3.1#hosting-generic-host-restricts-startup-constructor-injection

I wanted to see what would still work so I tried a few things.

You can no longer DI from Program in Startup.

But you can add a transient service and/or a singleton service to the ServiceCollection and use it within Program, and the rest of the application. You can also add a scoped service to the ServiceCollection and use it within the Program, it’s a little different from using transient and singleton so I’ll cover it in the next post.
Here’s how to use transient and singletons inside Program.
Create two services, creatively named ServiceOne and ServiceTwo and have them implement interfaces.

public class ServiceOne : IServiceOne
{
	public static int staticCounter;

	public ServiceOne()
	{
		staticCounter++;
	}
   //snip…

public class ServiceTwo : IServiceTwo
{
	public static int staticCounter;

	public ServiceTwo()
	{
		staticCounter++;
	}
	//snip…

I added a static counter to make it easy to see how many times the constructor is called.
For the transient one I expect it to increment every time the service is injected, for the singleton I expect it to remain at 1 for the lifetime of the application.

In Program.cs I split up CreateHostBuilder(args).Build call from the subsequent .Run().

public static void Main(string[] args)
{
	IHost host = CreateHostBuilder(args).Build();
	DoSomethingWithTheTransientService(host.Services);
	DoSomethingWithTheSingletonService(host.Services);
	host.Run();
}

The CreateHostBuilder() method is not changed –

public static IHostBuilder CreateHostBuilder(string[] args) =>
	Host.CreateDefaultBuilder(args)
	.ConfigureWebHostDefaults(webBuilder =>
	{
		webBuilder.UseStartup<Startup>();
	});

And I have two methods that use the ServiceCollection to access the registered services –

private static void DoSomethingWithTheTransientService(IServiceProvider serviceProvider)
{
	Console.WriteLine("Calling the transient service");

	var serviceOne = serviceProvider.GetService<IServiceOne>();
	Console.WriteLine(serviceOne.StaticCounter());
	Console.WriteLine(serviceOne.GetHashCode());
}

private static void DoSomethingWithTheSingletonService(IServiceProvider serviceProvider)
{
	Console.WriteLine("Calling the singleton service");

	var serviceTwo = serviceProvider.GetService<IServiceTwo>();
	Console.WriteLine(serviceTwo.StaticCounter());
	Console.WriteLine(serviceTwo.GetHashCode());
}

To make what’s happening more obvious I added the services to the constructor call of the WeatherForecastController() and added the counter and hash codes to the data returned by the action method.

public class WeatherForecastController : ControllerBase
{
	private IServiceOne _serviceOne;
	private IServiceTwo _serviceTwo;
	public WeatherForecastController(IServiceOne serviceOne, IServiceTwo serviceTwo)
	{
		_serviceOne = serviceOne;
		_serviceTwo = serviceTwo;
	}

For completeness, here is the ConfigureServices method in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IServiceOne, ServiceOne>();
    services.AddSingleton<IServiceTwo, ServiceTwo>();
    services.AddControllers();
}

Put some breakpoints in Program Main(), DoSomethingWithTheTransientService(), DoSomethingWithTheSingletonService() and in the WeatherForecastController.Get().

Start the application and browse to http://localhost:5000/weatherforecast to see what happens.

I’m going to follow up on this post with a version that shows how to use scoped dependencies in Startup .NET 5.

Full source code available here.

Executing a Method on All Implementations of an Interface

Full source code available here.

Have you ever wanted to execute a method on all implementations of an interface? Say you have an interface called IGenerator and four implementations of it – GeneratorA, GeneratorB, GeneratorC, and GeneratorD.
IGenerator is very simple, it has a single Generate(string details) method.

What I don’t want to do is –

var generatorA = new GeneratorA();
var generatorB = new GeneratorB();
var generatorC = new GeneratorC();
var generatorD = new GeneratorD();
generatorA.Generate(someDetails);
generatorB.Generate(someDetails);
generatorC.Generate(someDetails);
generatorD.Generate(someDetails);

I also don’t want to do this –

List<IGenerator> generators = new List<IGenerator>() { new GeneratorA(), new GeneratorB(), new GeneratorC(), new GeneratorD() } ;
foreach (var generator in generators) 
{
    generator.Generate(someDetails)
}

What I want to do is find all the implementations of the interface without explicitly naming them, create instances of the implementations and call the Generate(..) method. This way I can add a GeneratorE and GeneratorF and I’ll be sure their Generate(..) methods will be called.

Finding the Implementations

This code will find all the implementations of the IGenerator interface –

var iGenerator = typeof(IGenerator);
var generatorsTypes = AppDomain.CurrentDomain.GetAssemblies() 
    .SelectMany(assembly => assembly.GetTypes())
    .Where(type => iGenerator.IsAssignableFrom(type) && type.IsClass);

On line 1 I specify the type I am going to look for.

Line 2 gets all the assemblies, line 3 gets all the types in those assemblies. Line 4 limits the type to those that implement IGenerator and are a class, checking that the type is a class is important, because without it the interface itself would be included in the result.

Activating the Implementations

At this point all we have done is find the types, we have not instantiated them, so we cannot yet call the Generate(..) methods.
But of course there is a way to do just that.

List<IGenerator> generators = new List<IGenerator>();

foreach (var generator in generatorsTypes)
{
    generators.Add(Activator.CreateInstance(generator) as IGenerator);
}

Now I have a list with instances of all the implementations of IGeneraotor.

Calling the methods

Easy –

generators.ForEach(g => g.Generate("Hi from a generator."));

That’s it, find the implementations, activate them, call the method. The end.

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.

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.