HttpClientFactory in ASP.NET Core 2.1 (Part 3) Outgoing request middleware with handlers.

In my previous posts in this series (An Introduction to HttpClientFactory and Defining Named and Typed Clients) I introduced some core concepts and then showed some examples of using the new IHttpClientFactory feature in ASP.NET Core 2.1. It’s been a while since those first two posts but I’d like to continue this series by looking at the concept of outgoing request middleware with handlers.

IMPORTANT NOTE: the features shown here require the current preview build of the SDK and the .NET Core and ASP.NET Core libraries. I won’t cover how to get those in this post. At the time of writing we’re in preview 2 of .NET Core and ASP.NET Core 2.1. This preview should be reasonably feature complete but things may still change. If you want to try this out today you can get the preview 2 installers but I recommend waiting until at least the RC before producing any production code.

DelegatingHandlers

To be clear from the outset; many of the pieces involved in this part of the feature have existed for a long time. HttpClientFactory simply makes the consumption of these building blocks easier, through a more composable and clear API.

When making HTTP requests, there are often cross cutting concerns that you may want to apply to all requests through a given HttpClient. This includes things such as handling errors by retrying failed requests, logging diagnostic information or perhaps implementing a caching layer to reduce the number of HTTP calls on heavily used flows.

For those familiar with ASP.NET Core, you will also likely be familiar with the middleware concept. DelegatingHandlers offer an almost identical concept but in reverse; when making outgoing requests.

You can define a chain of handlers as a pipeline, which will all have the chance to process an outgoing HTTP request before it is sent. These handlers may choose to modify headers programmatically, inspect the body of the request or perhaps log some information about the request.

The HttpRequestMessage flows through each handler in turn under it reaches the final inner handler. This handler is what will actually dispatch the HTTP request across the wire. This inner handler will also be the first to receive the response. At this point that response passes back through the pieline of handlers in the reverse order. Again, each handler can inspect, modify or use the response as necessary. Perhaps for certain request paths you want to apply caching of the returned data for example.

 

IHttpClientFactory - DelegatingHandler outgoing middleware pipeline flow

In the diagram above you can see this pipeline visualised.

 

Much like ASP.NET Core middleware, it also possible for a handler to short-circuit the flow and return a response immediately. One example where this might be useful is to enforce certain rules you may have in place. For example, you could create a handler which checks if an API key header is present on outgoing requests. If this is missing, then it doesn’t pass the request along to the next handler (avoiding an actual HTTP call) and instead generates a failure response which it returns to the caller.

Before IHttpClientFactory and its extensions you would need to manually pass a handler instance (or chain of handlers) into the constructor for your HttpClient instance. That instance will then process any outgoing requests through the handlers it has been supplied.

With IHttpClientFactory we can more quickly apply one or more handlers by defining them when registering our named or typed clients. Now, anytime we get an instance of that named or typed client from the HttpClientFactory, it will be configured with the required handlers. The easier way to show this is with some code.

Creating a Handler

We’ll start by defining two handlers. In order to keep this code simple these aren’t going to be particularly realistic in terms of function. They will however show the key concepts. As we’ll see in future posts, there are ways to achieve similar results without having to write our own handlers.

To create a handler we can simply create a class which inherits from the DelegatingHandler abstract class. We can the override the SendAsync method to add our own functionality.

In our example this will be our outer request. A StopWatch will be started before calling and awaiting the base handler’s SendAsync method which will return a HttpResponseMessage. At this point the external request has completed. We can log out the total time taken for the request to flow through any other handlers, out to the endpoint over HTTP and for the response to be received.

Just to keep things interesting let’s create a second handler. This one will check for the existence of a header and if it is missing, will return an immediate response, short-circuiting the handler pipeline and avoiding an unnecessary HTTP call.

Registering Handlers

Now that we have created the handlers we wish to use, the final step is to register them with the dependency injection container and define a client. We perform this work in the ConfigureServices method of the Startup class.

The first two lines register each handler with the service collection which will be used to build the final service provider. These need to be transient so that a new instance is provided each time a new HttpClient is created.

Next, we define a client. In this example I’m using a named client for simplicity. Check out my previous post in this series for more detail about named and typed clients. The AddHttpClient method in this case returns an IHttpClientBuilder. We can call additional extension methods on this builder. Here we are calling the generic AddHttpMessageHandler method. This method takes the type for the handler as its generic parameter.

The order of registration matters here. We start by registering the outer most handler. This handler will be the first to inspect the request and the last to see the response. In this case we want our timing handler to record complete time taken for the whole request flow, including time spent in any inner handlers, so we have added it first. We can call AddHttpMessageHandler again, this time with our ValidateHeaderHandler handler. This will be our final custom handler before the inner HttpClientHandler is passed the request to send the request over the network.

At this point we now have an outgoing middleware pipeline defined on our named ‘github’ client. When a request comes through this client it will first pass into the TimingHandler, then into the ValidateHeaderHandler. Assuming the header is found the request it will be passed on and sent out to the URI in the request. When the response comes back it first returns through the ValidateHeaderHandler which does nothing with the response. It then passes onto the TimingHandler where the total elapsed time is logged and then finally is returned to the calling code.

Summary

While I have shown how easy it is to create a DelegatingHandler and then add it to your HttpClient outgoing pipeline using the new extensions; the team hope that for most cases you will not find yourself needing to craft your own handlers. Common concerns such as logging are taken care of for you within IHttpClientFactory (we’ll look at logging in a future post). For more complex but common requirements such as retrying failed requests and caching responses a much better option is to use a third party library called Polly. The team at Microsoft have made a great decision integrate with Polly.

In my next post I’ll investigate the options for adding Polly based handlers with IHttpClientFactory. In the mean time I suggest you check out this post by Scott Hanselman where he covers the Polly extensions. You can also check out the Polly wiki for more information.

Other Posts in this Series

Part 1 – An introduction to HttpClientFactory
Part 2 – Defining Named and Typed Clients
Part 3 – This post

Library Manager (LibMan) in Visual Studio 2017 (15.7) How to restore client side libraries in ASP.NET Core projects.

I recently started working on an ASP.NET Core 2.1 Preview 2 sample project. Having been mostly API focused recently, it was the first time that I’d done much with a site that actually renders views for a while. I found myself needing to re-learn my options for client side libraries.

My work on Humanitarian Toolbox is view based, however the project has grown up over a number of years and relies on a combination of NPM and gulp to bring in the required client side libraries.

For a brand new project, the templates will include a lib folder in wwwroot which has the necessary files which support the template features. However, if you’re checking into git, it’s quite normal to not include the lib folder, instead requiring the packages to be pulled on the client machine once cloned.

Full disclosure: I don’t consider myself a client side expert. I’m far more comfortable with the server side code! As such, this post is based on my own (potentially naive) approach to working with client side libraries.

Library Manager

Library Manager is a new feature included in Visual Studio 2017 (as of 15.7 preview 3) that provides new support for managing client side libraries in your projects. In this post I’m going to explore the basics of how I used this in a new project.

To add the Library Manager functionality to a project, simply right click on the project and choose the “Manage Client-Side Libraries…” option.

Manage client side libraries in Visual Studio 2017

This will add a single file to your project called libman.json. Note in the screenshot that at this point I don’t have a lib folder under wwwroot.

libman.json in solution

The libman.json file will be nearly empty when it’s first added. It includes a version and default provider. There is also an empty array of libraries defined. This is where we’ll add the packages we need for our project.

Default empty libman.json

In my example, my front end views only need bootstrap and jquery at this stage. Let’s look at how we can add those to our project. Each library is added as an object. There are a few properties we can set. The tooling offers autocomplete which makes populating this file a pretty straightforward experience. Here is an example of my final libman.json file.

Taking the boostrap entry as an example. The first value I provide is the name and version of the required library – “twitter-bootstrap@3.3.7”.

Next is the destination for the restored files relative to your project. In this case I’m including them under the wwwroot folder, in a directory called lib and then bootstrap.

Finally, in this example, I specify the individual files I want restored. This is optional. If you don’t include the array of files then all files from the library will be included. I preferred to be a little more selective about those that I needed here.

There’s also a value I’m not providing here to override the provider from which the library should be restored from. The provider options at this stage are cdnjs or filesystem.

Upon saving this file, the required libraries will be restored into your specified directory.

Restored lib folder in Visual Studio 2017

If you want to force a restore, perhaps after first cloning a project, you can do so by right clicking the libman.json file and choosing “Restore Client-Side Libraries”.

Restore client side libraries with lib man in Visual Studio 2017

Another option on this context menu is the “Enabled Restore on Build…” option. If you choose this option it will add a NuGet package to the project which will trigger the specified libraries to be restored on build. This is useful for CI / build servers for example (although I’ve not tested that at this stage). Choosing this option will present you with a dialog to confirm you wish to include the NuGet package.

Confirm adding Microsoft Library Manager build package

Once you do this a PackageReference will be added to you csproj file for “Microsoft.Web.LibraryManager.Build”.

CSPROJ after adding LibraryManager.Build

You’ll see the output from this when building your project. In this example I deleted the lib folder before triggering my build and you can see the files being restored as necessary.

Build output from libman.json (Library Manager)

That’s it for this post! I’ve not gone too deep into the tooling but so far this feels like a nice integrated way to specify and restoring client side libraries. Certainly I was able to get going with it pretty quickly and if it means I don’t need to learn about other client-side package managers and tooling, I’m pretty happy with that! I’m sure more seasoned client side developers will be better placed to judge this against the various other ways we can manage client side packages.

Updates to my ASP.NET Core Correlation ID Library Supporting correlation IDs across ASP.NET Core microservices.

Back in May 2017 I blogged about creating a simple library which supports passing correlation IDs between ASP.NET Core micro-services. The library came about because of a basic requirement we had at work to pass an identifier between related services to enable more useful error logging. By passing an identifier from the first service, through to any further services it then calls; if an exception occurs, we can quickly search for the entire history of that request across the distributed environment.

Since I released that first version to NuGet I have been staggered by the download stats. According to NuGet it now has nearly 27,000 downloads at the time of writing this post. I never really expected it to be used that heavily so this is a really pleasant surprise. I’m very pleased that something I’ve created is helping others with a similar requirement. It is a little daunting to think that so many people are dependent on that library in their code!

Three months ago I released version 2.0 of the library which added the concept of a CorrelationContext. This was a something I’d been considering almost immediately after completing version 1.0. An issue with v1 was that I’d chosen to set the TraceIdentifier on the HttpContext to match the correlation ID being passed in via the request headers. In controllers, where the HttpContext is accessible, this was not a major issue since the value of TraceIdentifier could then be read and used in logging. However, to use the correlation ID elsewhere, the only way to access it was via the IHttpContextAccessor. This isn’t registered in ASP.NET Core by default and so for some users of the library meant they would have to register it to make full use of the correlation ID.

I based my version 2 changes on the HttpContext and HttpContextAccessor in ASP.NET Core and this seems to have worked quite nicely so far. This required a breaking change for the library since it needed to register some services to support the new CorrelationContext.

Today I released version 2.1 of the library. This version adds two new configuration options that can be set when registering the middleware. One of these options came as a result of a GitHub issue requesting that it be possible to disable updating the TraceIdentifier with the correlation ID. This is now possible since the ID is passed around in the CorrelationContext and I needn’t rely on the HttpContext. To avoid breaking changes I added the option with it default setting behaving as it did before. I may look to change this default in the next major release.

I took the opportunity to add another new option that determines if the correlation ID should be matched to the TraceIdentifier or whether it should be a GUID in situations where an ID is not present in the header. For some users I can see this being useful and at work I’m considering the move to a GUID for our correlation ID.

A final change I was able to incorporate came as a result of another feature request via the projects GitHub issues. In this case it was to include the configured correlation ID header name on the CorrelationContext. This resulted in the first external PR on the project which I was very happy to receive. Thanks to Julien for his contribution.

I hope that people using the library are happy with these changes. As ever I’m happy to take feedback and ideas via GitHub if there are use cases that it doesn’t currently support.

UPDATE: It seems I wasn’t as careful as I thought about breaking changes. One did slip through in this release as I updated the interface and implementation for the ICorrelationContextFactory to support the new property on the context. If you’re consuming the library this is not something you generally need to access but if you’re mocking for unit testing it’s possible this will break there. Apologies! Turns out it’s harder than you think avoid breaking changes when released publicly!

ASP.NET Core Dependency Injection – How to Register Generic Types Exploring how generic types can be registered with the built-in Microsoft DI container

Since its release, ASP.NET Core has shipped with a “basic” Dependency Injection (DI) container included. This supports the functionality required to run the framework which was built from the ground up to support the use of DI throughout.

The ASP.NET documentation describes some general information about the use of DI in ASP.NET Core.

The documentation for the DI container (ServiceProvider) claims that its quite basic and not a replacement for more fully featured containers such as AutoFac or StructureMap for example. In my experience, for many of my requirements it has proved quite sufficient. In this short post I want to explore a less common registration requirement that may exist for some developers.

Imagine a scenario where you want to register a generic interface and a generic implementation with the ASP.NET Core DI container. In ASP.NET Core itself, an example of this use case is the ILogger<T> interface. We can ask for an ILogger<T> in constructors of our Controllers for example, where T is the Type that the logger will be logging for.

To put this more concretely; if we have a ValuesController and we want to log caught errors from our Actions, we can require an ILogger<ValuesController> in our constructor for the ValuesController. When the controller is constructed by the framework it will receive an implementation of the generic Logger<T> for our provided Type parameter. Under the covers the ILoggerFactory will use the type name to return the appropriate Logger. Messages logged via that logger will then include the full name of the Type (Namespace.ValuesController) when logged to the console for example.

A common way to register services with the ServiceCollection is using the generic extension methods. To add a Singleton registration for an interface and it’s concrete type for example we can call…

serviceCollection.AddSingleton<IService, MyService>();

The signature for the AddSingleton method is…

public static IServiceCollection AddSingleton<TService, TImplementation>(this IServiceCollection serviceswhere TService : class where TImplementation : class, Tservice

This works well for most scenarios but doesn’t work if we want to register generic services.

For a slightly contrived example, let’s say we have an interface like this…

And an implementation like this…

We want to be able to ask for an IThing<SomeType> in the constructor of a consumer which will get the correct GenericThing<SomeType> injected.

In this case we can use a different extension method on the ServiceCollection that accepts the types as parameters. Our registration would then look like this…

We now have our generic interface and implementation registered correctly. We can now consume this via DI wherever we need it injected.

Using HostBuilder and the Generic Host in .NET Core Microservices Exploring a simple pattern for cross-cutting concerns in console based services.

TL;DR;

The “generic” Host and HostBuilder are components  of a new feature set coming with the release of .NET Core 2.1. A use case of them is to simplify the creation of console based services by providing a pattern for adding cross-cutting concerns such as dependency injection, configuration and logging.

Introduction

Since ASP.NET Core 1.0 was released we’ve had the WebHostBuilder class which allows us to configure and build a WebHost. This then handles the lifetime of the application while the server (Kestrel) accepts and processes HTTP requests. In ASP.NET Core 2.0 the WebHostBuilder got some further refinement and simplification. The WebHostBuilder allows us to do things such as configuring services with a dependency injection container; quite often the container provided by Microsoft as part of ASP.NET Core. The WebHostBuilder also allows us to load configuration from multiple sources into a final configuration representation of Key/Value pairs.

The works extremely well for ASP.NET Core web applications, but there were no similar options in the framework for other types of application, until now!

NOTE: Please bear in mind that this post is written based on the ASP.NET Core 2.1 preview 1 release. Therefore, things may change during the public previews and also before the final release of 2.1 based on feedback received during those previews.

Introducing IHost and the HostBuilder

A new option available to developers working with .NET Core 2.1 is the new “generic” Host which enables developers to easily set up cross-cutting concerns such as logging, configuration and dependency injection for non-web focused applications. The team have realised that having the host tied to the concern of HTTP was perhaps not an ideal solution since many of these things are common requirements in other application types.

An example of where this could be used is in a console application which needs to run background processing tasks, perhaps handling messages on a queue for example. These types of services are now pretty common in a cloud native, container based architecture.

In the current 2.0 version of .NET Core it is certainly possible to utilise the logging, configuration and DI libraries within a console application. At work we have a number of microservices which do things such as processing messages from queues and data enriching tasks. We have to manually include and setup each of those common concerns ourselves.  Although this is possible, there’s some plumbing required to get things like DI setup within the application.

Building a Host

To create a Host we can use the new HostBuilder, which has a similar set of methods and extensions as the existing WebHostBuilder. The patterns should therefore be familiar to anyone working with ASP.NET Core currently.

There is one main difference to be aware of. The HostBuilder doesn’t provide an extension method that allows you to use a startup class as we can with the WebHostBuilder. This decision was made primarily to avoid the need to create two separate DI containers behind the scenes. With the generic host, a single service collection is configured and then used to build a the final service provider.

In the Main method for your application you can start by creating a HostBuilder and then use extension methods to register services with DI, read configuration and configure the logging that you need for your application.

The best way to explain the feature is with an example. If you want to view the full sample code you can pull it from GitHub.

If we take a look at the Main method for this console application, we can explore the creation of a Host for our application.

If you’ve used ASP.NET Core at all and have seen the WebHost builder, particularly in the 1.0 time frame, this might look quite familiar. We start by creating a HostBuilder which we can then use to define the Host we want to create. The first method in this example is the ConfigureAppConfiguration method. This method allows us to configure which configuration providers should be used to construct the final representation of configuration values for our application.

This is identical to the way that configuration can be customised when using the WebHostBuilder. In this example we have said that we want configuration values to be first read from an appsettings.json file, followed by environment variables and finally from any arguments passed into the application.

Next we call ConfigureServices which just as with the WebHostBuilder, allows us to register services with the ServiceCollection. Registration is performed using extension methods on the ServiceCollection and once complete, will enable us to get instances of those registrations wherever DI is available in our application.

In this case the first of these adds the ASP.NET Core Options services and the second sets up the registration for the IOptions binding. The final service registration is something I’ll come to a little later on.

The final section, ConfigureLogging as you might expect sets up logging for the application. In this case we add console logging, which uses the values from the application configuration to determine what to log.

The logging config in this sample is the same as found in a default ASP.NET Core web applications created using the templates.

The final step is to call RunConsoleAsync on the HostBuilder which builds and starts the application. It will then keep running until CTRL+C is used to trigger it to shutdown.

Getting Stuff Done

A service wouldn’t be much good if we left it here. At this point we just have a console application running, but not actually doing anything useful. Therefore we need a way to define the work which our application should perform.

The pattern that is recommended for this style of service is to utilise the new IHostedService feature, first introduced in ASP.NET Core 2.0. I wrote about this in a previous blog post.

Here we have a basic IHostedService implementation which will be run within this service…

I won’t go too deep into this code but I will summarise what it’s doing. When the application is started, it will call StartAsync on this service. Within that method we create a Timer which does some work every five seconds.

The work itself is defined in DoWork. Here is simply users the ILogger to log a message as information. This includes a message retrieved from the application configuration. This is accessed through the IOptions object passed into the service by DI.

At shutdown, StopAsync is called and the service cleans up a little before the application is killed. This is quite a contrived example but I wanted to keep things simply and focus on how the pieces fit together.

With the IHostedService implementation defined we simply have to register it with the DI container using the following common in ConfigureServices (which we saw earlier).

services.AddSingleton<IHostedService, PrintTextToConsoleService>();

We could add multiple hosted services if we needed to have various things running within this service.

Summary

There are quite a few cases for using this new “generic” Host concept. In this post we’ve explored a quite basic example, however I wouldn’t need much more than this to simplify a few of the microservices in our environment. Having a single common pattern for web applications as well as services, with easy access to things like DI, logging and configuration is extremely welcome.