~/codewithstu

Extending the AWS SDK for .NET

Transcript

Hi, my name is Stu and if you're new here, this channel is all about me breaking down different technologies into easily digestible chunks. In this video we're going to be taking a look at how to extend the AWS SDK for .NET. This can be very useful for different things like adding observability into the request pipeline so you know exactly what AWS calls you're making. The source code for this video is available in my GitHub repository and on my blog. There are links to both of these in the description below.

The approach that I'm going to show you in the video today is being actively used as described to implement distributed tracing with OpenTelemetry. Although I'm not going to show you that aspect of it here, I will show you how to extend the AWS pipeline. To demonstrate how to extend the AWS SDK, we're going to have a very simple application that simply lists all of the DynamoDB instances registered in the target system. In order to run this example you need to have a working LocalStack instance running with one or more DynamoDB tables created. If you want to copy the files that I've used, you can either grab them from the GitHub repository mentioned before or from the blog post in the description below. If you're using my files you should see the following when you run the program.

To start off extending the AWS SDK, we need to first import two namespaces. These are Amazon.Runtime and Amazon.Runtime.Internal. The AWS SDK provides an extensibility point inside the Amazon.Runtime.Internal namespace called RuntimePipelineCustomizerRegistry. This type is a singleton that allows you to register a class that customizes the pipeline. We are interested in a method called Register that takes an instance of IRuntimePipelineCustomizer. It's super important that you register your pipeline customization as early as possible so you can capture all of the AWS SDK calls. Once registered, an instance of the IRuntimePipelineCustomizer will be called every time a new pipeline is created.

The type that we need to implement is pretty trivial to implement as its main purpose is to add one or more pipeline handlers. When implementing this type we first need to check that the type that's passed in is assignable to AmazonServiceClient. This is so that we can safely ignore types that are invalid, such as mock types. To add our IPipelineHandler instance we need to call one of the three methods: AddHandler which adds to the end of the pipeline, AddHandlerBefore which adds before the specified handler type, or AddHandlerAfter which adds after the specified handler type. Generally speaking you want to add your handler after the endpoint resolver so you catch all retry items in any credential based calls, such as the ones to the IAM instance metadata service.

When we are implementing the IPipelineHandler we have two choices: implement the interface directly for maximum control, or inherit from the class PipelineHandler which is the one I recommend. This way we just override the methods that we need. We're not going to do anything fancy in our implementation here except record the AWS call to the console window. When you combine all of the code you should receive an output similar to the following. The instance of IExecutionContext that you're passed contains both the request and eventually the response object, plus other useful information like the application ID and whether the last exception was one that could be retried or not.

And that's pretty much it for this video. I hope that you find this extension point useful in your own codebase.

If you enjoyed this video, consider subscribing to the YouTube channel for more content like this.

// share_this