Simple Communications

Here’s a set of patterns that I’ve seen in other projects and used a number of times myself, with success. I’d like to share them with you. They revolve around communication over a network.

The first is more of a convenience than anything else, but I’ve enjoyed it so much, for such a long time now, that I think you might as well. It’s a fluent builder for constructing REST requests. As you probably deciphered, it’s a combination of the fluent interface pattern and a builder pattern, and it looks like this:

public class RequestBuilder
{
    private IRestRequest request;

    private static RequestBuilder Init(string resourceUri, Method method)
    {
        var resource = resourceUri.StartsWith("/", StringComparison.CurrentCultureIgnoreCase) 
            ? resourceUri.Substring(1) 
            : resourceUri;
        var builder = new RequestBuilder { request = new RestRequest($"api/{resource}", method) };
        builder.request.AddHeader(C.Headers.Accept, C.Headers.Json);

        return builder;
    }

    #region Static Constructors

    public static RequestBuilder POST(string resourceUri)
    {
        return Init(resourceUri, Method.POST);
    }

    #endregion
}
  1. The point here is that the entry point to this class is no-longer the constructor. It’s one of the static constructors, each representing an http verb (I’ve omitted the other http verbs for brevity, but you can check the gist for a fuller version).
  2. I’m using RestSharp here to build the rest request, but I’ve used multiple different libraries in other projects just the same for making requests (RestSharpPortable, and plain HttpClient being two others).

This isn’t very interesting yet, but it becomes so when you start adding the fluent builder methods that build up the request. Those look like this:

public RequestBuilder WithHeader(string key, string value)
{
    if (!string.IsNullOrEmpty(value))
    {
        this.request.AddHeader(key, value);
    }

    return this;
}

public RequestBuilder WithParameter(string key, string value)
{
    this.request.AddParameter(key, value);

    return this;
}

public RequestBuilder WithQueryStringParameter(string key, string value)
{
    this.request.AddQueryParameter(key, value);

    return this;
}

… which are all very simple, in and of themselves, but they lead to being able to write code that looks like this:

var request = RequestBuilder.GET($"v1/emeployee/{id}")
    .WithHeader(C.Headers.ContentType, C.Headers.Json)
    .WithHeader(C.Headers.Authorization, $"Bearer {auth.AccessToken}")
    .WithQueryStringParameter("key", "value")
    .Build();

Which, to my eyes, is very readable and really nice to work with (and code completion tools work really well with this as well).

I’m sure you are seeing the Build function and have a good idea what that might be… it’s here:

public IRestRequest Build()
{
    return this.request;
}

Simple and effective. I hope you use it and enjoy writing code with it.

Next post, I will show the next pattern, which often results on rock solid communication over a network.

Hope it helps!

Configuring .NET Core Command Line Applications with Config Files

There’s a fair bit of documentation out there about using the new Configuration functionality in ASP.NET Core, but I had far more trouble finding something that was more applicable to a CommandLine .NET Core application than I thought I would, especially something that didn’t have anything to do with CommandLine arguments.

Effectively, I’d like to replicate the kind of behavior that I’m used to having with an app.config, using config transforms, with the settings available globally in my application. The only difference for my situation is that I don’t have a need to update the settings at runtime, so I’m not considering that. Either way, here’s how I’m doing it.

First, add the requisite NuGet packages:

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Binder
  • Microsoft.Extensions.Configuration.FileExtensions
  • Microsoft.Extensions.Configuration.Json

Now add the following files to your solution:

Config.json

{
    "Config": {
        "MyNumberSetting" : 0, 
        "MyTextSetting" : "test"
    }
}

Config.Debug.json

{
    "Config": {
        "MyNumberSetting" : 1
    }
}

You can also have a Config.Release.json (or really, Config.[anything].json).

From here, I’ll use binding to have the configuration automatically deserialized into an object at startup. First things first: we need to make an object to hold the configuration settings. It should be named the same as the element in the config file that we want to deserialize, and the instance property names should match up as well. In this example, it looks like this:

public class Config {
    public int MyNumberSetting { get; set; }
    public string MyTextSetting { get; set; }
}

If you follow the docs, and examples online, you’ll find that the configuration binding will bind to an instance, but I said that I wanted the settings available globally. For that, this needs to be updated to:

public class Config {
    public int MyNumberSetting { 
        get { return MyNumber; }
        set { MyNumber = value; }
    }

    public string MyTextSetting { 
        get { return MyText; }
        set { MyText = value; }
    }

    public static int MyNumber { get; private set; }
    public static string MyText { get; private set; }
}

With this, when the config file is deserialized and mapped to an instance of this type, the instance setters will get hit and set the values of the static members. They have private setters, and so are mostly read only. You could still create a new instance, and call the setters, or use some reflection hijinks, but the private static member declares the intent well, and protects you from accidental attempts to update the value.

To load the settings, in Program.cs, I’m doing this on startup:

new ConfigurationBuilder()
    .SetBasePath(AppContext.BaseDirectory)
    .AddJsonFile("Config.json")
    .AddJsonFile("Config.Debug.json", optional: true)
//  .AddJsonFile("Config.[anything].json", optional: true)
    .Build()
    .GetSection("Config")
    .Bind(new Config());

That’s all that is needed to get global, (mostly) read only, application settings from configuration files in .NET Core. To access the values from anywhere, you can just do this:

int number = Config.MyNumber;
string text = Config.MyText;

Hope it helps!

Code available on GitHub.