Structuring a .NET Core application – Part 3

Settings

Before you begin reading this article, please take your time and read part 1, Structuring a .NET Core application – Part 1: Separation of Concern and part 2, Structuring a .NET Core application – Part 2: Inversion of Control first.

The previous two parts demonstrated how to split your application into smaller parts, each with their own small task, e.g. Separation of Concern. You’ve also seen how to use dependency injection in different types of applications in a standardized way with as little code reuse as possible. With each library handling all the registration of its services and dependencies.

In this part, we will move a bit back from our libraries and into the application side. In this part, we’re going to look into settings and how to use them.

You can find the source code for this article here: https://github.com/nickfrederiksen/net-core-structure/tree/part-3-settings

We have 3 libraries, used by four different applications. Each of our three libraries has services that requires some form of configuration.

The DAL library needs a connection string. The Azure Storage library needs some keys to access an Azure Storage account. And the email library needs some information about the SMTP server, the sender, CC, BCC and so on. To configure that, is quite easy. Just put all the configurations into a config file, load it up and we’re good to go. But is that really the best way to do that?

We have 4 different applications, each of these has different ways to handle configuration:

  • ASP.NET Core uses appsettings.json and environment variables.
  • Azure Functions uses environment variables
  • The console app uses command line arguments.
  • The UWP app doesn’t seem to have anything buildin, but we will have our settings stored in a settings.ini file, just for fun.

In .NET Core, you can mix and match all you want, and we can get appsettings.json functionality in all of our application types. However, each application type has its own usages.

The ASP.NET Core application is usually run on a web server of sorts, where config files can help setup multiple instances of the same application with the same settings.

The Azure Functions is running in a “serverless”, (read: hosted), Azure environment, where you might want to have your configurations managed by Azure, since we don’t really know, or care about, where the code is running. So, here we’ll use environment variables instead of a config file.

A CLI application could use a config file, but since it’s a console line interface application, I might want to have the settings be set as arguments instead of a file. This way we can easily batch different jobs, with different configurations and execute from the same folder.

And our UWP is a piece of end-user software. We cannot expect the end user to know how to modify a json/xml/text config file, set/change environment variables or load up some proprietary database file just to change the sender email address. In this case, we might want to build a “settings”-page within the application.

If we had to add logic, within all our libraries to handle each of these scenarios. Our code would be massively cluttered and full of duplicate code. So instead, we need to let our application do the configuration of our libraries instead.

But first, we need to modify our libraries so that they can be configured:

Please note, much of what I describe in this part is described in detail here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1

Configuring the services

To get started, we need to add a single nuget package to our libraries:

  • Microsoft.Extensions.Options.ConfigurationExtensions

This package will add an extension method to the IServiceCollection that looks like this: “Configure<TOptions>(Action<TOptions> configureOptions)”

You might know this method from ASP.NET Core, as it comes as part of that.

What it does is quite simple: First, it creates an instance of TOptions, then it calls the configureOptions action delegate to populate the options instance. Then it adds it to our DI using 3 different interfaces:

  • IOptions<TOptions>
  • IOptionsMonitor<TOptions>
  • IOptionsSnapshot<TOptions>

I won’t go into detail about these interfaces here but take a look at the link above. It describes it quite well.

So, we will configure our options using the Configure extension method and the we can inject, using DI, those options into our different services as needed.

First, we’ll need to create our options class. I usually create a folder called “Options” where I put my options classes. I will only show one example here but check out the code on github to see all of them.

public class AzureStorageOptions  
{  
    public string ConnectionString { get; set; }  
}

This example is for the Azure Storage project. And, as you can see, an options class is not very complex.

We will then register that option, using the Configure method from above:

services.Configure<AzureStorageOptions>((options) => options.ConnectionString = "connection string");  

See, simple. But wait. We have still not configured anything. Just hardcoded the connection string directly into our code. And further, we aren’t using the options anywhere.

That shit won’t fly!

Negan, A-hole extraordinaire – The Walking Dead

So, first of we need to move the configuration out of our library. To do that, I will just add the configureOptions task delegate to the, in this case, AddStorage method. And it will look like this:

public static void AddStorage(this IServiceCollection services, Action<AzureStorageOptions> configureStorage)  
{  
    services.Configure(configureStorage);  
  
    ... omitted ...  
  
}  

And thus, the configuration is no longer our concern. Excellent! Now we need to get rid of this abomination:

services.AddSingleton(provider => CloudStorageAccount.Parse("connection string"));  

We need to use the connection string from our options, and not this hardcoded value. And that is actually quite simple:

services.AddSingleton(provider =>  
{  
    var options = provider.GetRequiredService<IOptionsMonitor<AzureStorageOptions>>();  
  
    return CloudStorageAccount.Parse(options.CurrentValue.ConnectionString);  
});  

This code gets the options from the. And since we cannot run the application without it, it is fair to use “GetRequiredService”. We then use the current value of the options instance to get our connection string and pass it into the Parse method. Simple.

But there’s more. We have a QueueService, that has a hardcoded value as well. We have to move that out into our configuration logic as well.

So first up, we need to extend the options class:

public class AzureStorageOptions  
{  
    public string ConnectionString { get; set; }  
  
    public string QueueName { get; set; }  
}  

And currently, the QueueService looks like this:

public class QueueService : QueueClient<QueueModel>, IQueueService, IQueueClient<QueueModel>  
{  
    public QueueService(CloudQueueClient cloudQueueClient)  
        : base(cloudQueueClient, "queue-name")  
  
    {  
    }  
}  

We need to remove the hard coded “queue-name” and use the QueueName property from the configured options. And that is quite simple:

public class QueueService : QueueClient<QueueModel>, IQueueService, IQueueClient<QueueModel>  
{  
    public QueueService(CloudQueueClient cloudQueueClient, IOptionsSnapshot<AzureStorageOptions> options)  
        : base(cloudQueueClient, options.Value.QueueName)  
  
    {  
    }  
}  

As you can see, we just inject the options as an IOptionsSnapshot instance and use the value from there. And the wonderful part here is, that you can inject the options anywhere in your code. Not just within your library. But also, in the user interface or logging, not that you should log the connection string, but you could log or display the queue name in the UWP app and ignore the value in the ASP.NET application. It’s up to you. All that matters is that our library and its services has been configured.

Configuring the applications

All we need to do now, is to configure the applications themselves. And it’s also quite simple.

ASP.NET Core

Most of the ASP.NET Core configuration can be automated using the Bind() extension method on the IConfiguration interface. The extension method is located in this namespace: Microsoft.Extensions.Configuration.

All you need to do is update your call to the AddStorage method into this:

services.AddStorage(options => this.Configuration.Bind("azureStorage", options)); 

The Bind method, reads a section in the appsettings.json file called “azureStorage” and maps the values onto the passed in options instance.

Our appsettings.json then looks something like this:

"azureStorage": {  
    "ConnectionString": "connection string",  
    "QueueName": "queue-name"  
}  

As you can see, the json properties maps directly to the properties of our options class.

You might want to move the connection string into the “ConnectionStrings” section. That can also be done, quite easily: Please note: Do not have connection strings that points to your live database in your version control. That’s an easy way to get in the news.

By using the connection string section in the appsettings.json, we can configure our Azure App Services with connection strings more easily.

First, update the appsettings.json:

"ConnectionStrings": {  
    "azureStorage": "connection string",  
},  
"azureStorage": {  
    "QueueName": "queue-name"  
}

We also need to update our configuration code:

services.AddStorage(  
    options =>  
    {  
        this.Configuration.Bind("azureStorage", options);  
        options.ConnectionString = this.Configuration.GetConnectionString("azureStorage");  
    });  

First, we bind the settings from the “azureSettings” section, then we set the connection string from the connection strings section. That’s it really.

Azure Functions

Azure functions are a bit different in the way it handles settings. It uses environment variables instead of configuration files. However, in a local dev environment, it does have a configuration file: local.settings.json. And it might look something like this:

{  
    "IsEncrypted": false,  
    "Values": {  
        "AzureWebJobsStorage": "UseDevelopmentStorage=true"  
    }  
}  

Nothing radical. All we have to look at, is the Values section. This is a simple key-value object. Nothing special. So, we add the configurations for the Azure storage example at it looks like this:

{  
    "IsEncrypted": false,  
    "Values": {  
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",  
        "azureStorage-ConnectionString": "connection string",  
        "azureStorage-QueueName": "queue-name"  
    }  
}  

To use those values in our application, all we need to do, is to read the environment variables:

services.AddStorage(  
    options =>  
    {  
        options.ConnectionString = Environment.GetEnvironmentVariable("azureStorage-ConnectionString");  
        options.QueueName = Environment.GetEnvironmentVariable("azureStorage-QueueName");  
    });  

There you have it. And note that we don’t have to create an instance of the “AzureStorageOptions” class. It has already been instantiated.

You can read more about it here: https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash

Console applications

In our console application, in this example at least, we don’t want any configuration files. We want all our configurations to come from the argument list.

First up, we need to parse the argument list. This code is not pretty, but bear with me:

private static IReadOnlyDictionary<string,string> ParseArgs(string[] args)  
{  
    var values = new Dictionary<string, string>();  
  
    for (int i = 0; i < args.Length - 1; i++)  
    {  
        var key = args[i];  
        var value = args[i + 1];  
        if (key.StartsWith('-'))  
        {  
            key = key.Substring(1);  
            values.Add(key, value);  
        }  
    }  
  
    return values;  
}  

We then need to pass those values into the configuration code:

static async Task Main(string[] args)  
{  
    var configurations = ParseArgs(args);  
  
    var builder = Host.CreateDefaultBuilder(args);  
    builder.ConfigureServices((hostContext, services) =>  
    {  
        services.AddStorage(  
            options =>  
            {  
                options.ConnectionString = configurations["azureStorageConnectionString"];  
                options.ConnectionString = configurations["azureStorageQueueName"];  
            });  
    });  
  
    await builder.RunConsoleAsync();  
}  

Then, we can call the application like this:

IoCTest.Applications.CLI.exe -azureStorageConnectionString “connectionstring” -azureStorageQueueName “queuename”.

Universal Windows Application

As the previous examples show, we can store and retrieve our application configurations differently. But our services stay the same. The same goes for UWP applications.

But, instead of relying on environment variables, setting up appsettings.json or adding command line arguments. I will demonstrate how to read configurations from an ini file and use the values in our services.

First up: The config.ini file.

Create a file called config.ini. It is important, that this file is always being copied to the output directory:

Visual Studio file properties for the config.ini file with the “Copy to Output Directory” property set to “Copy always”

Otherwise the application cannot find the file.

Next up, add our values:

azureStorage-ConnectionString=connection string  
azureStorage-QueueName=queue-name  

Then, in the App.Services.cs file, we will load and parse the file: (I know, this logic should be put elsewhere, “Separation of concern” and all that. But for this example, I’m keeping it simple.)

private IReadOnlyDictionary<string, string> LoadSettings()  
{  
    var lines = File.ReadAllLines("./config.ini");  
    var values = lines.Select(l => l.Split("=")).ToDictionary(k => k[0], v => v[1]);  
  
    return values;  
}  

And then, set the values:

private void ConfigureServices(IServiceCollection services)  
{  
    var settings = this.LoadSettings();  
    services.AddStorage(  
        options =>  
        {  
            options.ConnectionString = settings["azureStorage-ConnectionString"];  
            options.QueueName = settings["azureStorage-QueueName"];  
        });  
}  

And that’s it. Four applications, four different types of managing configurations, 3 services all configured the same way.

TL;DR

Application settings, as the name implies, are application specific. You may have services shared across different application types. But the way each application handles configurations may differ from one another.

So, instead of letting the libraries do all the configurations and letting the guess what kind of application we’re running. We will let the application do the configuration for us, and then pass those down into our services in a standardized way.

Read more

If you haven’t already, please take a look at the other posts in this series:

Structuring a .NET Core application – Part 1: Separation of Concern

Structuring a .NET Core application – Part 2: Inversion of Control

Structuring a .NET Core application – Part 2

Inversion of Control

Before you begin reading this article, please take your time and read part 1 first: Structuring a .NET Core application – Part 1: Separation of Concern.

When building a service that has a dependency to a second, third or even fourth service. A sensible decision would be to just create new instances of those dependencies as you need them. It makes sense. I need a price calculation service therefore I create one and use it.

It makes sense to do so. Only create what you need when you need it. But what will happen if you need the price calculation service multiple places. You will end up creating multiple instances of the same service, and that could impact performance in a bad way. One way of handling this, is to add the dependent service as a parameter to the constructor and let someone else handle the creation of the dependent service. That is called Inversion of Control or IoC.

This post is not about IoC. But about how we can use that to our benefit by moving the creation and disposal of services away from our services into an IoC container. Luckily for us, such a container is baked into ASP.NET Core.

I will in this post show how to easily use IoC and register multiple services at once and use the same registration method in different .NET Core application types. From ASP.NET and Azure Functions to Console and Universal Windows applications. And yes, it is possible and quite powerful.

The Visual Studio Solution

To illustrate what we’re doing, I’ll have a solution with 7 projects:

  1. IoCTest.Web.Rest (ASP.NET)
  2. IoCTest.AzureFunctions.EmailService (Azure function)
  3. IoCTest.Applications.CLI (console app)
  4. IoCTest.Applications.Windows (uwp app)
  5. IoCTest.Integrations.Email (.NET Standard library)
  6. IocTest.Infrastructure.DAL (.NET standard library)
  7. IoCTest.Integrations.AzureStorage (.NET Standard library)

It might seem like a lot, but you’ll see, once you’ve done it once, you’ll be able to do them all. In an extraordinary short time. The solution here, took me about an hour and a half to setup. Yes, it has no business logic, but it does have a lot of moving parts. 1 hour 30 minutes from zero to 7 projects all referenced, IoC initialized, setup and ready to go.

The source code for this post can be found on GitHub right here:

https://github.com/nickfrederiksen/net-core-structure/tree/part-2-inversion-of-control

With ASP.NET Core came a build-in inversion of control container wrapped in a service called WebHostBuilder. This was meant for ASP.NET and ASP.NET only. But with .NET Core 3, came the new GenericHostBuilder. With this update came the ability to take many of the features available to ASP.NET and use them in new application types. It even makes it possible to mix and match. Hosting a rest api in a console app. Having console features in a web app, even Windows services. But that is out of scope for this series. For now, we will focus on one thing: Inversion of Control.

Just a side note: You can get the pattern I present her to work from a .NET Framework application using a DI like Ninject, Castle Windsor or LightInject. It’s a bit more cumbersome, and I won’t get into that since .NET Framework has a foot in its grave already.

Registering the services

Using the build-in service locator we need to register the services. That is done using the IServiceCollection interface from the host builder.

In an ASP.NET Core application, this is done in the Startup.cs class in the method “RegisterServices”. And it looks a lot like this:

ASP.NET Core, (Startup.cs):

private void RegisterServices(IServiceCollection services)  
{  
    services.AddScoped<IEmailClient, EmailClient>();  
}

Azure Function, (Startup.cs):

public override void Configure(IFunctionsHostBuilder builder)  
{  
    builder.Services.AddSingleton<IEmailClient, EmailClient>();  
}

Console application, (Program.cs)

builder.ConfigureServices((hostContext, services) =>  
{  
    services.AddSingleton<IEmailClient, EmailClient>();  
});  

Universal Windows Application, (App.xaml.cs)

IServiceCollection services = new ServiceCollection();  
  
services.AddScoped<IEmailClient, EmailClient>();  

As I wrote earlier, the inversion of control container is native to ASP.NET Core but we can make use of it in difference application types as well. I will demonstrate that later on.

This way of registering services is easy. Each application registers the services it needs and we are all happy. Or are we? If we look at the EmailClient, we can see it has two dependencies:

public EmailClient(  
    IEmailBodyGenerator bodyGenerator,  
    SmtpClient smtpClient)  
{  
    this.bodyGenerator = bodyGenerator;  
    this.smtpClient = smtpClient;  
}  

This means, that each application must register each of those services as well. And when the dependencies change, and it will in part 3 of this series, we will have to update each application and essentially copy and pasting code, creating duplicate code and that is bad. See part 1 on that.

What if we could make our email library do the work for us? The library ought to know about all its services and their dependencies? I think that’s a fair assumption.

When I build libraries like this, I like to make a Configurator class. What this class does is actually the same as you would in the above examples.

All you need to do is install the following NuGet package:

  • Microsoft.Extensions.DependencyInjection.Abstractions

However, if your library has a nuget package installed, that already has this dependency. You don’t need to install this one. That is the case with the DAL library, where the Entity Framework Core package has a dependency on this package already.

The configurator class has a static method, an extension method for IServiceCollection, and looks a bit like this.

public static void AddEmailServices(this IServiceCollection services)  
{  
    services.AddScoped<IEmailClient, EmailClient>();  
    services.AddScoped<SmtpClient>();  
    services.AddScoped<IEmailBodyGenerator, HtmlGenerator>();  
}

Note the naming. The method is named after what it does. This one adds all the services needed by the email library. If your library has multiple, independent services, you could add more of these extension methods. That’s up to you.

Now all we have to do in our startup.cs and their equivalents are this:

services.AddEmailServices();

And voilà, now the email services can evolve by themselves, all without breaking your applications or forcing you to update all the registrations.

I have come across multiple solutions where this is the case, been involved in quite a few of them myself before learning this “trick”. Which is why I choose to write about it here.

I know that it creates a dependency on a NuGet package on all our libraries, but I find the trade-off worth the while. Since we have separated the concerns into separate libraries, each with their own setup method, we have less duplicated code and decreased complexity. And we can reuse the same setup logic across several types of applications as well.

Feel free to go through the repo above to get into details on how I’ve implemented this.

Please bear in mind, that this is only for demonstration, not for production. The code builds and runs, but it needs a lot of configuration which I’ll dig into in the next part, and still has no business logic.

For now, let’s wire up the inversion of control containers for each of our applications:

Setting up Inversion of Control

As you know by now, ASP.NET Core already comes with an IoC container baked in so I won’t get into details on that. But I will take you through the other application types.

Console application

If you open up the IoCTest.Web.Rest project, you’ll see a Program.cs file. At first glance, it might seem odd that a web application needs a Program class just like a Console application. The reason is that an ASP.NET Core application, first and foremost, is a console app.

If you open the bin folder, you’ll see that is has created two files: IoCTest.Web.Rest.dll and IoCTest.Web.Rest.exe. The dll contains the code that we need to actually run the application. The exe file is the self-hosted application. A portable webserver that serves your application, just like IIS would do. If you run the .exe file, you’ll see something like this:

Example of an ASP.NET Core application running as a console application.
Example of an ASP.NET Core application running as a console application.

You can now go to http://localhost:5000 or https://localhost:5001. All this without setting up a local IIS or starting up an IIS Express instance.

This, to me, demonstrates perfectly, that an ASP.NET Core application is just a simple console application, with some services loaded and executed. And that opens for a whole lot of awesome.

If you think about it. If you can load up a web server from a console app. What kind of other stuff can you load up as well?

So, let’s look at our IoCTest.Applications.CLI project.

It has two files: HostedConsoleService, which we’ll look at later, and a Program file, pretty standard for a console application.

If you look at the Program.cs file from both the ASP.NET application and the console application side by side, you’ll notice a couple of things:

  1. They both call Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
  2. They both configure services, (the web app through the startup class)
  3. And they both call a Run method.

When you create a new .NET Core console app, you will not have access to the host builder. You will, in fact, have access only to a bare minimum of services for a .NET Core application. We need to install two NuGet packages to get that:

  • Microsoft.Extensions.Hosting
  • Microsoft.Extensions.Hosting.Abstractions

This will give us access to the generic host builder and the IHostedService interface, which I will dig into later.

All we need to do is to change our Main method a bit:

static async Task Main(string[] args)  
{  
    var builder = Host.CreateDefaultBuilder(args);  
    builder.ConfigureServices((hostContext, services) =>  
    {  
        services.AddSingleton<IHostedService, HostedConsoleService>();  
                  
        // TODO: Register services  
    });  
  
    await builder.RunConsoleAsync();  
}  

You’ll notice that I’ve change the signature a bit. With .NET Core 2.0 we finally got support for native async console applications. Which we need since our application host is going to run asynchronously.

The second thing you’ll see, is that I call Host.CreateDefaultBuilder(), exactly as I do in the ASP.NET Core application.

It then deviates a bit.

Instead of ConfigureWebHostDefaults, we call ConfigureServices. And instead of calling .Build().Run(), we call RunConsoleAsync().

The ConfigureServices method is our stand-in for the startup class. This is where we’ll register all our services. Including, the most important one: The IHostedService implementation HostedConsoleService.

Let’s dig into that one.

internal class HostedConsoleService : IHostedService  
{  
    public Task StartAsync(CancellationToken cancellationToken)  
    {  
        return Task.CompletedTask;  
    }  
  
    public Task StopAsync(CancellationToken cancellationToken)  
    {  
        return Task.CompletedTask;  
    }  
}  

Nothing. Absolutely nothing. But it’s still very important.

In a normal console application, the Main method is our entry point. This is where we instantiate and run everything. But not in this case. In this case, we register our services and starts a generic host from our Main method. But our host is no good host if it has no services to host. Hence the IHostedService. This class is now our entry point. We can create a constructor and add all the services we need like this:

private readonly IEmailClient emailClient;  
  
public HostedConsoleService(IEmailClient emailClient)  
{  
    this.emailClient = emailClient;  
} 

And then we can use the IEmailClient service. Of course, we need to register it first, but you get the gist.

A note: Normally a console app closes automatically after completion. Not in this case. We need to tell our application to stop. To do so, just inject the Microsoft.Extensions.Hosting.IHost interface and call the host.StopAsync() method when you need to stop the application. Otherwise it keeps running until ctrl+c is pressed, or the console is closed.

A second note: In a web context, a scoped service is created once in the beginning of a request and reused until the request ends. In console applications and UWP applications, you need to manage the scopes yourself. I will not dive into this here, as it is out of scope for this series.

Azure Functions

From the very beginning, Azure Functions was build almost the same way as basic console applications: A static class with a static method with your code. It’s all good for small tasks. But if you have a set of methods doing different tasks on the same libraries it quickly gets complicated when you have to initialize every single service one by one, for every dependent service as well. And doing it for multiple Azure Functions. There was some rudimentary dependency injection, but only for a few known services and definitely not for custom services.

This has changed with .NET Core 3 and the Azure Functions v3 API. Now we can have a startup.cs and use the approach described earlier on.

All we need is two NuGet packages:

  • Microsoft.Azure.Functions.Extensions
  • Microsoft.Extensions.DependencyInjection

The latter, I find, is self-explanatory. The former, is what makes magic possible. It exposes an abstract class called, Microsoft.Azure.Functions.Extensions.DependencyInjection.FunctionsStartup.

All we have to do now, is to create a new class, Startup.cs, inherit from this class and implement the Configure method.

Oh, and one thing: We need to tell the runtime that we have a startup class, otherwise it won’t use it. To do that, we need to add this to our class file:

[assembly: FunctionsStartup(typeof(IoCTest.AzureFunctions.EmailService.Startup))]  
namespace IoCTest.AzureFunctions.EmailService  

The FunctionsStartupAttribute is found in the namespace Microsoft.Azure.Functions.Extensions.DependencyInjection.

It is important, that this line of code is located outside of the namespace as it contains information that is needed by the runtime during assembly load.

All it does, is telling the runtime to create an instance of the class registered and start the application from here.

The Configure method, gives us access to an instance of IFunctionsHostBuilder. At the moment, it doesn’t contain much, but it do contain a single property: Microsoft.Extensions.DependencyInjection.IServiceCollection Services { get; }.

And you will notice, that the IServiceCollection matches the one we have been using to register all our services. So now, we can do something like this:

public override void Configure(IFunctionsHostBuilder builder)  
{  
    var services = builder.Services;  

    services.AddEmailServices();  
    services.AddDatabaseAccess();  
    services.AddStorage();  
} 

Brilliant! But how can we inject these fine services into our static Function class. Easy: First remove the “abstract” keyword from the class and method definition. Add a constructor that takes the services you want to use, and the use them in your function:

public class Function1  
{  
    private readonly IEmailClient emailClient;  
  
    public Function1(IEmailClient emailClient)  
    {  
        this.emailClient = emailClient;  
    }  
  
    [FunctionName("Function1")]  
    public Task Run([TimerTrigger("0 */5 * * * *", RunOnStartup = true)]TimerInfo myTimer, ILogger log)  
    {  
        return emailClient.SendEmailAsync("[email protected]", "[email protected]", "Sent from a Azure Function using IoC", new { text = "This is so awesome!" });  
    }  
}  

Simple as that.

As you can see, three different application types, all using the same service registration logic. And now for something a bit more complicated:

Universal Windows Application

I have little to none experience with Universal Windows Applications, or UWP Apps. I did a bit of WPF development back in the day, but it has definitely been a long time since.

This example is merely to demonstrate how to use the same methodology as above, but in a completely different environment. UWP apps are not console applications. They work in a completely different way compared to web applications and are not service based as Azure Functions. I will not dig into scope management as I’m too unfamiliar with the API’s to do so. But I will show how you could build inversion of control into you UWP app and reuse the same services as your other applications. Without any hazzle, well maybe a little, let’s see:

First you need to install three NuGet packages:

  • Microsoft.Extensions.DependencyInjection
  • Autofac
  • Autofac.Extensions.DependencyInjection

Since UWP’s, as of writing, does not have inversion of control natively, we need to use an external IoC container. In this case, Autofac. And you’ll see why, later.

As you might have noticed, I like to separate things into separate parts by concern. The same goes for this next part.

Any application has an entry point. UWP apps has one called App.xaml and a corresponding App.xaml.cs. We want to extend this a bit. So, first things first: Create a new file called App.Services.cs. In this file, you should create a single partial class called “App”:

public partial class App  
{  
  
}

In here we’ll add a public static property that contains the IoC container and a method called ConfigureServices().

In here, we’ll setup Autofac and register our services:

public partial class App  
{  
    public static IContainer ServiceContainer { get; private set; }  
    private void ConfigureServices()  
    {  
        var containerBuilder = new ContainerBuilder();  
        IServiceCollection services = new ServiceCollection();  
  
        services.AddScoped<IEmailClient, EmailClient>();  
  
        this.ConfigureServices(services);  
  
        containerBuilder.Populate(services);  
  
        ServiceContainer = containerBuilder.Build();  
    }  
    private void ConfigureServices(IServiceCollection services)  
    {  
        services.AddEmailServices();  
        services.AddDatabaseAccess();  
        services.AddStorage();  
    }  
}  

That’s it really. Remember to include these namespaces: Autofac, Autofac.Extensions.DependencyInjection and Microsoft.Extensions.DependencyInjection.

Now we only need to call our “ConfigureServices” method from the App class and we are golden. For this example, I do it from the constructor. You might want to do it somewhere else to better manage resources when going back and forth between pages and the suspended state. You might know this a lot better than I.

To get one of your services, all you have to do is call the Resolve<> method on the App.ServiceContainer property:

public sealed partial class MainPage : Page  
{    
    public MainPage()  
    {  
        var emailClient = App.ServiceContainer.Resolve<IEmailClient>();  
  
        this.InitializeComponent();  
    }  
} 

You’ll notice that we don’t have dependencies in the constructor. At the time of writing, it is very complicated to get that working, so this method will do for now.

You can read more about Autofac and how to register and resolve services here:

https://autofaccn.readthedocs.io/en/latest/resolve

In the next part, I will dig into how to use all of this for configuration. Allowing the same services to be configured from completely different configuration sources. It is almost scary how easy and reusable it is.

TL;DR

It is very easy to build a large number of small services and reuse these services across different kinds of .NET Core applications. By using IoC intelligently.

It is also easy to maintain all these small services, registering them, updating, adding and removing them. Without breaking all your applications with one standardized method.

It might take a bit of configuration for some of the application types, but it is all “set and forget”. Have you done it once, you will never have to think about it ever again.

Read more

If you haven’t already, please take a look at the other posts in this series:

Structuring a .NET Core application – Part 1: Separation of Concern

Structuring a .NET Core application – Part 1

Separation of Concern

Note, this series is very theoretical, and this first part especially, and might be for less experienced developers, but there should be something for everyone.

There are many ways to build an application, many right ways to build one and many wrong ways. I’m not the one to say the way you build your applications are wrong. I might be wrong; I might be right and so can you. It all depends on how you work best in your organization and under your circumstances.

With this post, I’m going to describe what I think is the best approach to application development anno 2020. Namely splitting up your code into separate blocks and services.

Previously, when I was less experienced as I am today, I used to build applications in large chunks. It’s easy. I need an application that takes X and splits it into A, B and C. A is going into a database, B and C is going to different external services.

Large methods

So, my application would have one large method, Save(X). That method would handle everything: Open a connection to the database, save A, close the database connection. Then, open a connection to External Service 1, post B, close the connection. And finally open a connection to External Service 2, post C and then close the connection.

It’s quite simple. Everything is there. My method does exactly as is advertised, (sort of), and it does get the job done.

Then, the next day, I need another method to only send B to External Service 1. Well, that’s easy. Open a connection to the service, post B and then close the connection again. Easy. Everything is fine, everything is working as expected and everyone is happy.

But one day, External Service 1, updates their API. There are new URL’s and a new authentication model. Everything in my application breaks. Who can fix it? I might, but it’s been a while since I’ve worked on that application, so my memory is a bit rusty. So, I try to remember all the places where I call the service and update to the new API. I might miss a few places, but those places are the ones not easily tested, so errors might only occur after a while. Had one of my colleagues gotten the job, the chance of failure would be very high!

This pattern of copying code from one place to another, is called duplicate code. In my experience, duplicate code occurs when you just need to add a feature or fix an error, quickly. Or, it might happen when the developer lacks the experience to foresee problems ahead of time. The latter certainly was the case for me for some time. Later it was the former.

If you need to copy and paste code, you’re doing something wrong.

Søren Spelling Lund, CPO, uCommerce

I’ve heard this quote many years ago, but it has stuck with me ever since, and I try to do my best not to copy and paste code. Well, we all copy and paste from Stack Overflow, but you know what I mean.

One of the problems with code duplication, besides the difficult maintainability, is that it, more often than not, results in huge methods and classes that attempts to do everything at once. Take our Save(X) example above. It does three things at once. It makes sense, since it has to split X into separate parts and send those parts to different services. But it has way too much responsibility. It has the responsibility to package and serialize the data into the formats each of the services requires. It also has the responsibility to open and close connections to each service and it has the responsibility to handle errors returned from each service. And most importantly, none of it can be reused. It has all that responsibility, and can only use it for that very specific task that is to save X.

Save(X) might look something like this:

public void Save(X){  
    // Split X into A, B and C  
    // Open the database connection  
    // Map A into a database entity  
    // Close the database connection  
  
    // Open a connection to External Service 1  
    // Serialize B into json  
    // Send json to External Service 1  
    // Close the connection to External Service 1  
  
    // Open a connection to External Service 2  
    // Serialize C into XML  
    // Send XML to External Service 2  
    // Close the connection to External Service 2  
}  

What we need, is to relieve Save(X) of some of its responsibilities. Save(X) should only have one responsibility: Save X.

This is called Separation of Concern.

We need to identify every small part of the application and separate them into small reusable snippets. Where each snippet has one responsibility. And only one.

Again, let’s take our Save(X) example from above.

It can be split into 3 parts, which again can be split into, at least, three parts each.

Separation of Concern

What we need to do, is to separate everything into small, easily reusable and maintainable snippets with as few responsibilities as possible. This is called Separation of Concern.

Database

Save(X), needs to store data into the database. We can separate that logic into a library that does that. The library has three responsibilities: Manage database connections, package/transform/serialize the data and store it in the database.

The first part is building a class that only has one concern: Database connection, let’s call it DatabaseConnection. It has two methods: Open () and Close (). This is a very simplistic setup and mostly theoretic, bear with me on this.

It might look like this:

class DatabaseConnection  
{  
    public OpenDatabaseConnection Open()  
    {  
        // Open the connection.  
    }  
  
    public void Close()  
    {  
        // Close the connection.  
    }  
}

Open () returns a database connection that can be used to send data to/from the database. Our Save(X) could just use this and be over with it. Save(X) no longer has the responsibility of knowing how to open a database connection or how to close it. But it still has the responsibility of knowing how the data is formatted and sent to the database.

Therefore, we need another class: UnitOfWork, (again, simplistic and theoretic. More details in upcoming posts).

This class has the responsibility to send data through an open database connection with a method called SaveData(). And since we’ve just made a class with the sole responsibility of maintaining the database connection, our UnitOfWork class can utilize this class. If we choose to make a new UnitOfWork, we can make use of the same database context class and not have any duplicate code between our two unit of works, other than calls to the Open() and Close() methods.

Our UnitOfWork class could look like this:

public class UnitOfWork  
{  
    private readonly DatabaseConnection databaseConnection;  
    public UnitOfWork(DatabaseConnection databaseConnection)  
    {  
        this.databaseConnection = databaseConnection;  
    }  
  
    public void SaveData(string tableName, object data)  
    {  
        this.databaseConnection.Open();  
        // Save the data    
        this.databaseConnection.Close();  
    }  
}  

We could add a third layer, called Repository, (I know, using Entity Framework, NHibernate and the like, the repository pattern is redundant). What this class does is package the data and send it to the database. And since we’ve just made a class that has the responsibility of sending data to the database, our Repository only has one concern: Package the data. And then send that data to our UnitOfWork:

public class Repository  
{  
    private readonly UnitOfWork unitOfWork;  
    public Repository(UnitOfWork unitOfWork)  
    {  
        this.unitOfWork = unitOfWork;  
    }  
  
	public void SaveA(AModel data)  
	{  
		// Map A into a database entity.    
	
		this.unitOfWork.SaveData("dto.A", mappedData);  
	}  
}  

We have now separated the concern of managing the database connection, mapping to a database entity and saving that entity to the database, away from our Save(X) method, it now looks like this:

public void Save(X){  
	// Split X into A, B and C  
		
	Repository.SaveA(A);  
	
	// Open a connection to External Service 1  
	// Serialize B into json  
	// Send json to External Service 1  
	// Close the connection to External Service 1  
	
	// Open a connection to External Service 2  
	// Serialize C into XML  
	// Send XML to External Service 2  
	// Close the connection to External Service 2  
}  

Much simpler, and we can now reuse Repository.SaveA() multiple places without thinking about changes to the database connection, database schema or future development.

Service clients

As with the database abstraction we did above, we can also split our service clients into separate parts with single responsibilities.

But first, lets break it down a bit.

We have, again, three responsibilities: Manage a connection to a service, serialize data and send data.

I feel lazy, so for the first part we’ll be using a build-in service called System.Net.Http.HttpClient. This service / client manages everything related to HTTP requests. Hence the name HttpClient. It handles opening and closing connections, so we don’t have to think about that. For now.

But we still need to serialize data before we can send it through the HttpClient.

We know we have to serialize at least two different kinds of data into, at least, two different kinds of string data, (JSON and XML). Let’s start by defining a reusable interface that does just that:

public interface IDataSerializer<TModel>  
{  
    System.Net.Http.HttpContent Serialize(TModel model);  
} 

This interface describes a service that converts a model of type TModel into an instance of HttpContent.

We can then create two services:

public class BSerializer : IDataSerializer<BModel>  
{  
    public System.Net.Http.HttpContent Serialize(BModel model)  
    {  
        /// serialize to json. ... omitted for brevity  
        return new System.Net.Http.StringContent(jsonString, System.Text.Encoding.UTF8, "application/json");  
    }  
}  
  
public class CSerializer : IDataSerializer<CModel>  
{  
    public System.Net.Http.HttpContent Serialize(CModel model)  
    {  
        /// serialize to xml. ... omitted for brevity  
        return new System.Net.Http.StringContent(jsonString, System.Text.Encoding.UTF8, "text/xml");  
    }  
}  

These two services each has one responsibity: Convert data to a format that can be sent to the service. Please note, these are very simplified examples.

We now handle the serialization part. What we need is a service that can send that data to our service endpoints. I like to call a service like that something like ServiceClient.

Our ServiceClient has two dependencies: HttpClient and an instance of IDataSerializer<TModel>. It also has a method called SendData that takes an instance of TModel and sends it through our HttpClient.

A such client could look something this:

class ServiceClient<TModel>  
{  
    private readonly System.Net.Http.HttpClient httpClient;  
    private readonly IDataSerializer<TModel> serializer;  
      
    public ServiceClient(  
        System.Net.Http.HttpClient httpClient,   
        IDataSerializer<TModel> serializer)  
    {  
        this.httpClient = httpClient;  
        this.serializer = serializer;  
    }  
      
    public System.Threading.Tasks.Task SendDataAsync(TModel model){  
        var serializedContent = this.serializer.Serialize(model);  
        return this.httpClient.PostAsync("path to service", serializedContent);  
    }  
}  

Again, very simplified. This client only handles a single model type and can only do HTTP Post requests. But then again, it’s for illustrative purpose only.

Please note, managing the HttpClient happens elsewhere. The serialization logic has also been moved elsewhere. The only thing this class does, is sending serialized data through the HttpClient.

Our Save(X) method above would then look something like this:

class SaveXample  
{  
	
	private readonly Repository repository;  
	private readonly ServiceClient<BModel> externalService1;  
	private readonly ServiceClient<CModel> externalService2;  
	
	public SaveXample(  
		Repository repository,  
		ServiceClient<BModel> externalService1,  
		ServiceClient<CModel> externalService2  
		)  
	{  
		this.repository = repository;  
		this.externalService1 = externalService1;  
		this.externalService2 = externalService2;  
	}  
	
	public async System.Threading.Tasks.Task Save(XModel X)  
	{  
		this.repository.SaveA(X.A);  
		await this.externalService1.SendDataAsync(X.B);  
		await this.externalService2.SendDataAsync(X.C);  
	}  
}  

As you can see, much simpler. The only responsibility this class now has, is to split X into A, B and C. Saving A to the database is handle elsewhere. B and C is being handled elsewhere also. Some of the logic that handles B and C is reused. And it’s extensible. We can, quite simple, add a new service that sends C data as a binary stream by only creating a new IDataSerializer class.

The next part will be much more in dept into how I would organize and build libraries in a .NET Core application. Including how to wire up services like the ones described in this post and use dependency injection efficiently and reusable across applications.

TL;DR

Splitting code into small libraries, small classes and small methods. Has a lot of benefits:

1: Easier to maintain

It’s easier to maintain 10-20 lines of code doing one thing, than it is to sieve through 100s of lines of code that does everything to fix a bug.

It’s also easier to make changes without impacting the entire application. You can mark methods obsolete; you can change dependencies, interfaces and schemas without impact.

2: Reusability

When splitting your application into smaller pieces, you can reuse those pieces multiple places. And fixing an error in one of those pieces, means fixing it everywhere.

Reusability also opens up for unit testing. Having separated everything into separate parts, you can mock-up all dependencies and only test essential code.

You can even reuse your code across different applications, say an ASP.NET Core application and an Azure Function. Both can use the same library. And changes in that library will not impact either of them.

3: Scalability

By separating everything, you can build more efficient code, reducing memory footprint and CPU usage. You can implement caching strategies and manage disposables within each library / module / class / method.

4: Cons

By splitting everything into smaller pieces, one must be aware of changing the interfaces and contracts. Since the code you are changing can be used places you don’t know about.

A method that does one thing, must keep doing that one thing. All code that calls that method, expects it to do that one thing. Changing it to do another thing, is unexpected behaviour and might result in errors. Such changes must be made in a different method / class marking the old one obsolete if needed.

The developer must think of everything that depends on that library as external. It might be the developer him/her self that builds those applications, but after 4 weeks, he/she is definitely a different developer.

Making an ASP.NET Core front-end for WordPress – 1

I always try to find an excuse to code, I just love doing it. It rarely ends in a real life usable product, but I’m having a blast doing it.

For my latest project, I thought I would bring you around, just to get back into the blogging game, but also to keep my self on a schedule to, at least try to finalize this project.

Description

It’s no secret, my blog runs on WordPress, it has done so since 2007. I have tried, many times to move to Umbraco, but I never really got there, so here we are.

This project, is a way for me to start that transition. I want to move all public content away from the CMS, into a standalone application based on ASP.NET Core. This way, I will be able to isolate my WordPress backend and have a greater control over my frontend.

I will also like be able to try switching to Umbraco Headless or a full, local, Umbraco install without changing the frontend or needing to rebuild the front-end completely.

I usually use Visual Studio for my programming, but I will try to make this post as “cross platform” as possible.

My project names are all prefixed with NDesoft, feel free to call yours what you want.

I will also use my own WordPress API endpoint, feel free to use that as well. Everything is cached by Cloudflare, so go nuts.

Resources / Documentation

I am using the following resources to help me along in this endeavor:

ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/index?view=aspnetcore-2.1

.NET Core CLI: https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x

WordPress Rest API: https://developer.wordpress.org/rest-api/

Requirements

It must be based on ASP.NET Core.

Data access must be isolated from the web app, making it possible to add an App, Rest API or whatever later on without changing the code base.

CMS Api access must be isolated in a way that more can be added later on without rebuilding the applications completely from scratch.

This might make the project a bit over-engineered, but hey, we’re just having some fun here!

Getting started

First you must find a folder suitable for development. There, you open up a console, I prefer PowerShell, and run this command:

dotnet new sln

This creates a new Visual Studio solution file, nothing to it other than that.

Next we create a folder for our application, I call mine for “NDesoft.App”

In this folder we will create a new ASP.NET Core project, using the MVC template:

dotnet new mvc; dotnet sln ../NDesoft.sln add ./NDesoft.Web.csproj

This will create a new ASP.NET Core MVC project, and add it to our solution file.

Next, we need two more projects: One for wrapping the WordPress API, and one used as an interface between the web-app and the WordPress wrapper:

dotnet new classlib -o NDesoft.Wrapper;
dotnet new classlib -o NDesoft.Wrapper.WordPress;
dotnet sln add NDesoft.Wrapper;
dotnet sln add NDesoft.Wrapper.WordPress;

This will create two new folders, each with their own class library, (dll), project and add them to our solution file.

In each folder, the template has created a file called Class1.cs, please delete that. We don’t need that.

We’ll need to add some references between our newly created projects, to make them play nice together.

NDesoft.Web must have a reference to NDesoft.Wrapper and NDesoft.Wrapper.WordPress

NDesoft.Wrapper.WordPress must have a reference to NDesoft.Wrapper

To do that, we need to run the following commands:

dotnet add NDesoft.Web reference NDesoft.Wrapper NDesoft.Wrapper.WordPress;
dotnet add NDesoft.Wrapper.WordPress reference NDesoft.Wrapper;

Packages

We also need to install a few packages:

Newtonsoft.Json, AutoMapper and AutoMapper.Extensions.Microsoft.DependencyInjection

Automapper is used later on, but we might as well install it now.

dotnet add NDesoft.Web package automapper;
dotnet add NDesoft.Web package AutoMapper.Extensions.Microsoft.DependencyInjection;
dotnet add NDesoft.Web package Newtonsoft.Json;
dotnet add NDesoft.Wrapper package Newtonsoft.Json;
dotnet add NDesoft.Wrapper.WordPress package automapper;

And now, our solution and projects are up and running and we can start coding.

Interfaces

ASP.NET Core has native dependency injection, and since we are building a highly decoupled platform it makes sense to utilize that. So let’s start by adding a ton of interfaces. These will just be the bare minimum for this post, more will come.

In the NDesoft.Wrapper project, we’ll add a folder called “Interfaces” and under that another called “Helpers”.

In the Helpers folder, we’ll create to interfaces, (One file per interface):

IRequestManager

This interface manages requests to the Rest API and deserializes the responds, I might add an interface for the deserialization, but for now it’s handled by this manager.

public interface IRequestManager
{
    Task<TResult> Get<TResult>(string url, CancellationToken cancellationToken, object parameters = default);
}

IUrlParameterHelper

This interface helps us handle URL parameters in a shared way. No copy/pasting anything.

public interface IUrlParameterHelper
{
    string ConvertToUrlParameters(object parameters);
}

In the “Interfaces”-folder, we’ll create two new interfaces:

IPosts

This is an interface that handles everything related to blog posts. It has nothing to do with authors, tags, categories, media, comments, pages and so on, only posts.

Please note the “PostModel”-class, this will be implemented in a bit.

public interface IPosts
{
    Task<IEnumerable<PostModel>> GetPosts(int currentPage = 1, int? pageSize = default, CancellationToken cancellationToken = default);
}

IClient

The name might change, I do not like the name, but for now it’s IClient. It’s the main entry point handling almost everything.

public interface IClient
{
    IPosts Posts { get; }
}

Classes

Now we have the basic interfaces going, let’s implement them.

First of we need a class that represents a single blog post:

NDesoft.Wrapper

PostModel

Place this class in a folder, in the NDesoft.Wrapper project called “Models”.

public class PostModel
{
    public string Id { get; set; }
    public DateTime Date { get; set; }
    public DateTime Modified { get; set; }
    public string Slug { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public string Excerpt { get; set; }
    public string AuthorId { get; set; }
    public string FeaturedMediaId { get; set; }
    public bool IsSticky { get; set; }
    public IEnumerable<string> CategoryIds { get; set; }
    public IEnumerable<string> TagIds { get; set; }
}

This class is based off of the response from the following request for a single post:

GET https://ndesoft.dk/wp-json/wp/v2/posts/873

The properties contains, what I think is, the minimum required number of properties to display a blog post. You might want more or less.

You might want to add a reference to this class in the IPosts interface.

RequestManager

In NDesoft.Wrapper create a folder called Helpers. In here, create a class called RequestManager:

public class RequestManager : IRequestManager
{
    public static readonly HttpClient httpClient = new HttpClient();
    private readonly string baseUrl;
    private readonly IUrlParameterHelper urlParameterHelper;
 
    public RequestManager(string baseUrl, IUrlParameterHelper urlParameterHelper)
    {
        this.baseUrl = baseUrl;
        this.urlParameterHelper = urlParameterHelper;
    }
 
    public virtual async Task<TResult> Get<TResult>(string url, CancellationToken cancellationToken, object parameters = default)
    {
        var fullUrl = this.GetFullUrl(url, parameters);
 
        var response = await httpClient.GetAsync(fullUrl, cancellationToken).ConfigureAwait(false);
        response.EnsureSuccessStatusCode();
 
        var bodyContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
 
        var result = JsonConvert.DeserializeObject<TResult>(bodyContent);
        return result;
    }
 
    protected virtual string GetFullUrl(string url, object parameters = default)
    {
        var parameterString = this.urlParameterHelper.ConvertToUrlParameters(parameters);
        return $"{baseUrl}{url}{parameterString}";
}
}


Worth noting: The constructor takes a string as first parameter. It contains the base URL of the Rest API. The value is, later on, set using app settings. However, I would like to not add it as a parameter, since it adds to the complexity of setting up the dependency injector.

Also noteworthy, this class has a static readonly HttpClient. This way we always use the same HttpClient for all requests. I do know about RestSharp and the like, but I prefer HttpClient as I thinks it’s easier to use.

I have a habit to always pass a Cancellation token into every async method that supports it. To me it makes sense because if a user aborts a request, every subrequest I make on my site will be aborted as well releasing resources.

It might be beneficial to add some caching here to reduce response times and load on the source server.

UrlParameterHelper

Next to the RequestManager, add a class called “UrlParameterHelper”:

public class UrlParameterHelper : IUrlParameterHelper
{
    public string ConvertToUrlParameters(object parameters)
    {
        if (parameters == default)
        {
            return string.Empty;
        }
 
        var type = parameters.GetType();
        var properties = type.GetProperties();
        var urlBuilder = new StringBuilder();
 
        if (properties.Any())
        {
            urlBuilder.Append("?");
            string joinedParams = GetParameterString(parameters, properties);
            urlBuilder.Append(joinedParams);
        }
 
        return urlBuilder.ToString();
    }
 
    private static string GetParameterString(object parameters, PropertyInfo[] properties)
    {
        var urlParams = new List<string>(properties.Count());
        foreach (var property in properties)
        {
            var value = property.GetValue(parameters);
            if (value != null)
            {
                var stringValue = value.ToString();
                if (string.IsNullOrWhiteSpace(stringValue) == false)
                {
                    var encodedValue = HttpUtility.UrlEncode(stringValue);
                    var urlParam = $"{property.Name}={encodedValue}";
urlParams.Add(urlParam);
}
}
}
var parameterString = string.Join("&amp;", urlParams.ToArray());
    return parameterString;
}

This class is used to help converting an object to url parameters, making it easier to create url’s with objects rather than string manipulation.

In the future, this class might be extended to handle number and datetime formatting better than it does now, as well as flattening nested properties.

Client

And now, the last class in the NDesoft.Wrapper project, before moving on to the WordPress specific classes. This class should be located in the root of the project.

public class Client : IClient
{
    public Client(
        IRequestManager requestManager, 
        IPosts posts)
    {
        this.RequestManager = requestManager;
        Posts = posts;
    }
 
    protected IRequestManager RequestManager { get; }
    public IPosts Posts { get; }
}

There’s nothing much to this class at the moment, but we will add more in a future post.

NDesoft.Wrapper.WordPress

Now we move on to some of the WordPress specific implementations.

Models

This is not a class but a folder, we need to create a lot of classes that represents the json returned from the WordPress Rest API, and instead of me posting all those classes I’ll tell you how to generate all those classes.

First get the Json, I use Postman:

GET https://ndesoft.dk/wp-json/wp/v2/posts/873

Copy the response body and:

In Visual Studio:

Edit -> Paste Special -> Paste JSON As Classes

Or use http://json2csharp.com/

Posts

In the root of the project, add a class called Posts:

public class Posts : IPosts
{
    private const string BaseUrl = "/wp/v2/posts";
    private readonly IRequestManager requestManager;
 
    public Posts(IRequestManager requestManager)
    {
        this.requestManager = requestManager;
    }
 
    public async Task<IEnumerable<PostModel>> GetPosts(int currentPage = 1, int? pageSize = null, CancellationToken cancellationToken = default)
    {
        var parameters = new
        {
            page = currentPage,
            per_page = pageSize
        };
 
        var response = await requestManager.Get<IEnumerable<Post>>(BaseUrl, cancellationToken, parameters).ConfigureAwait(false);
        return Mapper.Map<IEnumerable<PostModel>>(response);
    }
}

Some background here: The method “GetPosts” loads all posts from the API by calling this URL:

GET https://ndesoft.dk/wp-json/wp/v2/posts

However, loading all posts at the same time would be overkill and slow down response times and over time only become slower. So, we need to add some paging parameters to the URL.

How to do that, we’ll look at this page https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/ it tells us that the API has two parameters we can use for our needs: “page” and “per_page”. Page, oddly enough is not zero-based so the first page is “1”.

PostProfile

Speaking of AutoMapper, we need some configuration to map the weird WordPress models the more leaner PostModel class. To do that, we need an AutoMapper profile.

Create a folder called “AutoMapperProfiles” and add a class called PostProfile:

public class PostProfile : Profile
{
    public PostProfile()
    {
        CreateMap<Post, PostModel>()
            .ForMember(dest => dest.Date, m => m.MapFrom(src => src.date_gmt))
            .ForMember(dest => dest.Modified, m => m.MapFrom(src => src.modified_gmt))
            .ForMember(dest => dest.Title, m => m.MapFrom(src => src.title.rendered))
            .ForMember(dest => dest.Content, m => m.MapFrom(src => src.content.rendered))
            .ForMember(dest => dest.Excerpt, m => m.MapFrom(src => src.excerpt))
            .ForMember(dest => dest.AuthorId, m => m.MapFrom(src => src.author))
            .ForMember(dest => dest.FeaturedMediaId, m => m.MapFrom(src => src.featured_media))
            .ForMember(dest => dest.IsSticky, m => m.MapFrom(src => src.sticky))
            .ForMember(dest => dest.CategoryIds, m => m.MapFrom(src => src.categories))
            .ForMember(dest => dest.TagIds, m => m.MapFrom(src => src.tags));
    }
}

Again, nothing special here. All we do is we flatten out some of the weird constructs of the WordPress json and maps everything to a more lean model.

Web

Now we have setup everything needed to access the WordPress API and have a solid base to build on. All we need to do now is wire everything up in the web project.

Configure AutoMapper

First things first, we need to configure AutoMapper. Open up the Startup-class and add the following method at the bottom of the class:

private void SetupAutoMapper(IServiceCollection services)
{
    services.AddAutoMapper(cfg =>
    {
        cfg.AddProfile(typeof(PostProfile));
    });
}

All we do here is adding AutoMapper to our services, and adds our PostProfile to the AutoMapper collection.

Setting up the Dependency Injector

Next up, adding our services to the Dependency Injector. Again in the Startup-class add the following method to the bottom of the class

private void SetupWrappers(IServiceCollection services)
{
    services.AddTransient<IUrlParameterHelper, UrlParameterHelper>();
    var baseUrl = Configuration["WrapperConfig:BaseUrl"];
    services.AddTransient<IRequestManager, RequestManager>((provider) => new RequestManager(baseUrl, provider.GetRequiredService<IUrlParameterHelper>()));
    services.AddTransient<IClient, Client>();
 
    // Service specifics:
    services.AddTransient<IPosts, Posts>();
}

All we do here is telling the DI, what services we have, and where to find their implementations. Note that everything uses the NDesoft.Wrapper classes, but only Posts uses the NDesoft.Wrapper.WordPress classes.

Before we’re done here, we need to add the following to the appsettings.json-file:

"WrapperConfig":{
      "BaseUrl":"https://ndesoft.dk/wp-json"
 }

By doing this, we tell the wrapper where to find the endpoints needed to get the data.

Finishing up Startup

In the ConfigureServices-method, add these two lines at the top of the method:

this.SetupAutoMapper(services);
this.SetupWrappers(services);

And now we are set, and can start building our controller.

Home

In the HomeController, remove everything except the Index-method and add the following:

private readonly IClient client;
 
public HomeController(IClient client)
{
    this.client = client;
}

This injects the client into the controller and we’re ready to use it.

Replace the Index-method with this:

public async Task<IActionResult> Index(CancellationToken cancellationToken)
{
    var posts =  await this.client.Posts.GetPosts(1, 5, cancellationToken).ConfigureAwait(false);
    return View(posts);
}

This code gets the first 5 posts from my blog and sends them to the view.

Final thing, we need to update the view. Open the file /Views/Home/Index.cshtml and replace everything with this:

@model IEnumerable<NDesoft.Wrapper.Models.PostModel>
@using System.Globalization;
@{
    ViewData["Title"] = "Home Page";
}
 
@foreach (var item in Model)
{
    <article>
        <a href="/@item.Date.ToString("yyyy/MM/dd", CultureInfo.InvariantCulture)/@item.Slug"><h2>@Html.Raw(item.Title)</h2></a>
        <div>@item.Date</div>
        <div>
            @Html.Raw(item.Content)
        </div>
    </article>
}

Trying it out

Let’s try to run the darn thing:

dotnet build;
dotnet run --project ./NDesoft.Web;

You should now be able to go to http://localhost:5000 or https://localhost:5001 and se something like this:

Source

The source code for this blog post can be found on Github:

https://github.com/nickfrederiksen/aspnetcore-wrapper-for-wordpress/tree/part-1

Next part

In the next part, I’ll try getting pages, author, tags and categories up and running.

Why I haven’t posted any articles since 2014

Back in 2014 I wrote a blog post about a new package I’ve created for Umbraco called “Create magic with APE“, that was my last post I did before this one. And here is why.

Please note, this is not a technical post, this is a very personal one so if you don’t like that, please move along.

In school I was, like so many other skinny pale nerds with a vocabulary of an adult, bullied. A lot. So much in fact that even the teachers either wouldn’t or couldn’t help. I was alone in school, I was alone at home.

The bullying presented it self in many ways. The usually “You’re ugly” and “You’re a nerd”, the later I’ve learned to embrace as a positive thing, was a mostly daily routine. But the occasional someone-tells-a-joke thing, was probably some of the worst. It would go like this: Some one tells a joke, everybody laughs, me included. Everybody turns to me and shouts “Why are you laughing”. Those things hit me the hardest, and has stuck with me ever since.

November ’98, 20 years ago, snow had fallen and the entire schoolyard and football field was covered in 10+ cm of snow. Btw. I love snow, always have, always will. And this story hasn’t changed that fact! For some reason, the school had decided that all pupils were not allowed to be indoors in the breaks, so we where all to go outside. There where one rule though: No snow tossing in the schoolyard, only on the football field. So, naturally, knowing my fellow students, I decided to stay in the schoolyard. For safety.

But, it didn’t take long before people came to me and started tossing snow at me. And it wasn’t even people from my own class, not even my year. It was people from the classes below AND above, that joined in on this fun game of covering the crying nerd in as much snow as possible. That was it. The teachers shrugged it away as “hormones” and “children will be children”. Less than one week after, on november 25th 1998, I started in the school where my grandmother and mother went to.

It was a private school, few pupils, looong waiting line. This being an emergency, and my family’s history with the school, it took one phone call and a I was out of hell!

I loved it there, no bullying, great teachers and awesome environment. Even though it took 2 hours a day on a bus just to get to school, I loved it there. Best 2½ years of my life at that point.

After that, not much happened. Experienced a bit of bullying later on, but as time went on I found my self in great company among other nerds and geeks making the bullying bearable. But the damage was still there.

At 18, I went to a psychologist for a few sessions because my then-girlfriends mother told me to, so I indulged her. The psychologist and I talked for a few sessions and in one of them he looked at me and told me these words exactly, well, he did say them in Danish, and it was 13 years ago:

I have never met, or heard of, one that has gone through so much hardship and still be alive to talk about it. You are the, mentally, strongest person I have ever met.

Those words has ever since been imprinted into my mind and to this day, has helped me a lot.

The years went on, and other than me having a few trust issues and some problems connecting to people and taking contact to people, I managed getting an education and a job. Yeah! I even bought my self a house!

Everything went OK, I began blogging quasi-seriously, stirring the Umbraco-pond on more than one occasion. I went to CodeGarden, became more and more active in my professional field as well as a volunteer at Odense Filmfestival. Everything was going the right way for me.

Bang! 2015 came along. I loathe 2015. This is the worst year of my adult life.

My company had just landed two major orders in Copenhagen, that meant that 4 developers was to go to Copenhagen every week for 6 months. That meant, back at the office we had: 1 full time designer, 2 or 3 interns and me.

As the senior, the only senior, everything went through me. Every small support task, every single task, went directly through me. No one else had the skillset that I had, so I had to coordinate a lot of things, on top of my own projects.

At first, I didn’t really notice it, but the projects I worked on began to fail. I almost couldn’t write a single line of code without it having bugs. This meant, frustrated customers, and a frustrated boss. When I began to notice this trend, I told my boss and colleagues, that I couldn’t handle anyting else. I could not work on more projects, I had reached my limit. I fact, I realized, I had crossed my limit. What was the reaction? “Just work longer”.

It became so bad at one point, that I have lost whole weeks that I cannot remember. I have no recollection of what I was doing or why. All I knew was I was at work, I could the se commits in our source control, but I could not remember ever doing them. I you haven’t tried it, that shit is scary as hell. What else had I forgotten?!

Summer 2015. I broke down. I, a grown ass man, was sitting in my chair in the office in front of my boss and colleagues, crying. At that point, it dawned on everyone what they had put me through. It also dawned on me, that I have been overworked for so long that something inside me has broken.

I began noticing something was off, I wasn’t myself anymore. I wasn’t normal. It was pointed out to me, unrelated, that I had som characteristics in common with Sheldon Cooper from the sitcom “The Big Bang Theory”. I knew, because I’m a nerd, that Sheldon is being portrayed as having Asperger’s Syndrome, a type of autism. So, I decided to see a psychiatrist.

We talked, for 5 hours, spread over 2 sessions, and he concluded that I did not have Asperger’s. Yeah f-ing yeah! I did, however, have semi-severe social anxiety with a mild depression caused by the massive bullying in school, buried for years and violently pulled back to the surface by the massive stress I’ve endured for 6-8 months.

But that didn’t mean the end of things. As I refuse to take any “mind altering drugs” like anti-depressives, I went to see a psychologist instead. We talked for 6-7 session, maybe more, can’t remember. And she gave me some tools and some guiding on “mindfulness” and meditation, that I have since done to some extend on a semi-regular basis whenever I feel stressed out.

It’s noteworthy, that through all of this, I had my company backing me up. They pulled people back from Copenhagen and accepted that I, at this point, still cannot work after hours. When I’m off, I’m off, and they support me 100%. Today, the slightest sign of stress, on anyone, is being handled up front. People are now, more than ever, encouraged to not work more than needed.

That year, 2015, caused so much havoc to my mind that I have ever since struggled doing what healthy people would do in a heartbeat. It can take anything from ½ an hour to several weeks for me to call someone on the phone. Sending an email, a text, even a comment takes a lot of effort for me to do. I cannot participate in online games without matchmaking, because I then have to engage with strangers. Doing tasks like calling for a plumber to fix the pipes in my house, also takes a lot of effort. Almost every socializing or interaction with other people is a struggle. Even writing this post.

I have so many posts in my head, and so many things I want to do but it takes a lot of effort for me to do at this point. But, as this post shows, I’m going in the right direction. One step at a time.

If you have been, or are, bullied as a kid or an adult. Talk to someone. Anyone. It will come back and do a lot of harm, just a matter of time. If you know someone that gets bullied, be that someone to talk to. You may save a life.

This is a long, personal, post that has taken 4 years to write, well 3 hours of actual writing, and is meant for me as a beginning to start blogging again and as a test of the changes I’ve made to my hosting environment, but more on that later.

Feel free to leave a comment, it should work, share on twitter, facebook, linkedin or whatever.

PSA: I am NOT in anyway, trying to harm myself. At all! Just to make sure you guys know that. After all this shit I’ve been through, I love my life, and I love living it. So don’t worry about me.

Create magic with APE

I would like to present to you, “APE”. APE stands for “Awesome Property Extractor” and is simply a framework for extracting properties and their values from arbitrary data and turn them into strongly typed C# properties and values.

To begin with, we have created a package for Umbraco called APE.Umbraco.

What is APE.Umbraco

APE.Umbraco is a nuget package for extracting Umbraco properties and dictionary items and transform them into strongly typed C# properties that can be accessed using “dot-notation”.

APE accesses the database and retrieves all dictionary items, doctypes and their properties and data types, and builds a bunch of strongly typed classes.

These classes give you access to all the values without ever opening the Umbraco back office, just to look what a given alias or dictionary key was called. All you need to know is what doctype the property is on, and you can access all the properties, said doctype has, even those that has been inherited. You can even “dot” your way to all the doctypes, using a common static class called DocTypes, we even have a class called Dictionary!

We have created two releases of this package:

  • APE.Umbraco v1.0, this release is built for Umbraco 6 and does not support Umbraco 7, for that we have,
  • APE.Umbraco v2.0, this release is built for Umbraco 7, and does not work with Umbraco 6!

1.0 is released to support “old” sites and will not be updated unless a bug is reported. 2.0+ is the one we will build upon and add features to.

What’s in the package

The package contains the following:

APE.Umbraco.dll, this is the “magic box”. This assembly is merely an implementation of the method described in my earlier post.

This folder tree:

  • Classes
    • APE
    • Cms

The APE folder contains a FileManager.ttinclude file. This file allows us to split the generated classes into multiple files, improving readability. It will be released with each APE.* release.

The Cms folder contains two T4 templates: Umbraco.Dictionary.tt. This template, extracts all dictionary items from the database using the umbracoDbDSN connection string and generates a class containing all dictionary keys and a class for getting dictionary values using said keys. The other file is Umbraco.DocTypes.tt. It uses the same connection string to extract all document types and their properties, maps the Umbraco data into C# classes and properties into a class pattern like the one I described in my previous post, “Umbraco and .NET magic”.

The future

In the future we will have an APE.UCommerce package and many other APE packages. You can help us making APE the best alternative to Code First on platforms not build to support Code first, like Umbraco and uCommerce. A long with the release of APE.Umbraco, we are making the whole deal open source on GitHub:https://github.com/LAITDK/AwesomePropertyExtractor. This is also the place to find documentation and code examples, post bug reports and make pull requests.

It’s awesome! Where can I get it?!

As this package is intended for developers it is only released through NuGet. There will not be an Umbraco Package. It just makes no sense to create an Umbraco package for something that needs Visual Studio to work, (I don’t know if it works in WebMatrix).

To get the package, look no further. https://www.nuget.org/packages/APE.Umbraco/

To see examples on what APE can do, take a look at the wiki: https://github.com/LAITDK/AwesomePropertyExtractor/wiki

Hope you like the package and will help making this the goto package for any Umbraco project.

Umbraco and .NET magic

Wouldn’t it be fun, if you could simply call one method on an IPublishedContent, and get any property as the right type, always, without parsing or converting the data, passing any type-parameter or calling different methods? Wouldn’t it be cool if said method knew that a rich text editor property is always an IHtmlString and a content picker is an IPublishedContent rather than a string or an integer? Wouldn’t it be awesome if the same method returning an IPublishedContent could return an integer or a string with no additional code other than a type parameter? And how about this method is seamlessly put on top of Umbraco without interfering with existing code, but still used in the same manner?

Would your mind be blown if I told you it is possible and how to accomplish exactly that?

Basic theory

The idea behind this “method” is basically this:

“Everytime I need a property I have to call GetPropertyValue(), add a type parameter, and a magic string with the alias of the property from which I want the value.

Nine out of ten times, that value is either a string or an int that I have to parse or convert to a different type. Why do I have to pass two values each time? And what if said property is a content picker? I can’t pass IPublishedContent as a type parameter. How should umbraco know if I want a media item or a content item?

If we could “learn” umbraco to automatically give me the right value each time, so I don’t need to know if this property is a string, a media item or a DateTime. It would make our lives a bit easier.

Let’s take a look at some code

First off, we need to know what type, each of our properties have. So we look into our doctypes and each of their properties. We need two informations: Alias and Data Type.

Then we make a small class. Nothing big, just a small one:

public abstract class DocTypeProperty
{
     protected DocTypeProperty(){}

    public string Alias {get;set;}
}

This class contains half of what we need, but it’s okay.

Please note, it’s marked as abstract, and it constructor is protected. This is because, it’s purpose is not to be instantiated directly, but to serve as a base / master class, that has to be inherited.

Then we need to store our data type. This is where magic begins:

public class DocTypeProperty<TValue>
{
    public DocTypeProperty() : base(){}
}

Is that it?! No!! As I wrote: “The magic begins”.

We have now both information needed to perform the real magic, we know the alias of the property and the type we want the data as. As the smart developer you propably are, you have noticed that I have no parameters in my constructors. That is correct. More on that later.

To instantiate our “DocTypeProperty’s” we do this:

var myProp = new DocTypeProperty<string>(){ Alias = “someAlias” }

Please take note of the variable name: “myProp”. We are going to need that later.

How and when you do this I will not tell in this post, as it’s a complete post on its own. All I can tell is T4 templating IS an option!

So now we have our alias, and the type we want to convert the value into. But we are not done yet.

As I wrote ealier, I would like this to be seamlessly integrated on top of umbraco, but I cannot just pass my DocTypeProperty into the GetPropertyValue-method as is. To do this, we need to add an implicit operator, that can “transform” our neet DocTypeProperty to an old school string containing our alias:

public static implicit operator string(DocTypeProperty prop)
{
    return prop.Alias;
}

Now we can do this:

SomeContent.GetPropertyValue<string>(myProp);

This works exactly like oldschool umbraco. No magic yet, other than the implicit operator.

Now we need to get rid of the type parameter. To do this, we need to add an extension method to IPublishedContent:

public static class PublishedContentExtensions
{
    public static TValue GetPropertyValue<TValue>(this IPublishedContent content , DocTypeProperty<TValue> property)
    {
        return content.GetPropertyValue<TValue>(property);
    }
}

This will result in an overload to the standard umbraco GetPropertyValue-method.
Now, we can do this:

SomeContent.GetPropertyValue(myProp);

See, simple. This will return the value of the property as a string. But this is great for standard data types, but what about other types like media pickers, content pickers, multiitem whatever picker? We still need to learn our DocTypeProperty-class, how to handle those types.

So we add this method to the generic DocTypeProperty:

public virtual TValue Map(IPublishedContent content)
{
    return content.GetPropertyValue<TValue>(this);
}

This is the generic / default mapper. It handles all default umbraco data types, like string, DateTime, int and so on.

Furthermore, we need to update our own GetPropertyValue()-method:

return property.Map(content);

So this is all jolly, but we still need to be able to get an IPublishedContent instead of just an integer with a node/media id. To do this, we need to override the mapper:

public class MediaPickerProperty : DocTypeProperty<IPublishedContent>
{
    public override IPublishedContent Map(IPublishedContent content)
    {
        var umbracoHelper = new UmbracoHelper(UmbracoContext.Current); // This should not be done each time we call this method. Put it outside in a cached field!
        return umbracoHelper.TypedMedia(content.GetPropertyValue<int>(this));
    }
}

Now we can make an instance of the MediaPickerProperty:

var myMediaProp = new MediaPickerProperty(){ Alias = “someMediaPicker”};

Again, note the property name. Now I have a few options:

The old fashioned:

someContent.GetPropertyValue<int>(“alias”) // returns an int.
someContent.GetPropertyValue<int>(myMediaProp) // Also returns an int.

and the new:

someContent.GetPropertyValue(myMediaProp) // Returns IPublishedContent.

And if I did this:

someContent.GetPropertyValue(myProp)

It would return string.

But let’s say we have myProp registered as DocType<string>, but I would like it as an IHtmlString more than just once, but not as often as I want it as string. I don’t want to have the same property registered twice. And what if I have more properties that needs to be IHtmlString once or twice?

Well, first we need to define an IHtmlStringProperty-class, and create a mapper. Like we did with the MediaPickerProperty. The mapper however, is a bit simpler, just:

return new HtmlString(content.GetPropertyValue<string>(this));

Now I need to be able to transform my DocTypeProperty<string> into my IHtmlStringProperty.

To do this, as simple as possible, we need to add a method to the base DocTypeProperty:

public TProp As<TProp>()
    where TProp : DocTypeProperty, new()
{
    return new TProp() { Alias = this.Alias };
}

It doesn’t get any simpler than that. And now you can see why I needed to have a parameterless constructor. Otherwise, this would have been a pain in the arse.

So now I can do this:

someContent.GetPropertyValue(myProp) // string

someContent.GetPropertyValue(myProp.As<IHtmlStringProperty>()); // IHtmlString

As you can see, this is completely transparent. You can write less code. , and you don’t have to remember hundreds of aliases, and update each and everyone of them when they change. You have the alias registered once. Especially if you autogenerates the properties using T4. You can always go back to umbraco’s own GetPropertyValue. Just add a type parameter. You have complete control over what types your property values are fetched as and the code is 100% reusable!

We use this approach, including the T4 templating, in all our new projects, and we are able to put upon existing applications, without interfering with code already written.

Real MVC App using Umbraco – revisited

So, it seems that my latest post has generated a lot of debate throughout the umbraco community. Thank you!

Me and my coworkers at Lund & Andresen IT (in Danish), has been using this method for a couple of months now, and we’ve found a couple of issues that I didn’t think of. But now I have taken in some input from the community as well as from my coworkers and now I am revisiting the method.

The main theme throughout the post still remains: No data access or umbraco logic in the views! The views must only display what they are being served. Nothing more, nothing less.

Where I was wrong

In the old post, I suggested that all doctypes must be mapped to a model using a mapper class. This is no longer true! The problem quickly showed it self when building a large site: With mappers, we essentially get waay to much data per view, and we generalize how data is extracted without taking in account for different circumstances. An other problem was that our controllers no longer have any work to do, other than calling a mapper and serving a view. So my MVC (Model View Controller) became a “MMVC” (Model Mapper View Controller), which was not intended.

Sample project

As promised on twitter, I have made a simple sample project that illustrates my points. Please feel free to download it and tell me what you think.

What has changed

Not that much has changed. I have only redefined the mapper roles and reinstated the controller roles:

Models

I have two types of models in mind for a basic umbraco site:

  • Document type model
  • Data model

Document type models represent real document types. They have the same inheritance structure as doctypes, meaning if a doctype is a child of a master doctype so must the representative model.
So if you have a doctype tree looking like this:

  • MasterDocType
    • TextPage

Then you will have these two models:

public class MasterDocTypeModel{}
// Please note, we inherit from the MasterDocTypeModel:
public class TextPageModel : MasterDocTypeModel {}

This way, when you add a property on the MasterDocType, you will only have to add said property on one model.

Besides containing properties mapped from a doctype, a Document Type Model, may also contain other properties, like menu items.

Data models are models that are not in any way related to doctypes. A great example is for menus. You don’t want to build an entire document type model for each item and descended items in a menu tree, when the only information you want are “Name”, “Url”, “IsActive” and “ChildNodes”.

This is where data models come in. A menu would list NavigationItemModels instead of a mixture of TextPageModel, NewsArchiveModel and so on and so forth.

Controllers

Controllers are more important than ever!

Controllers are the ones that builds models and serves them to the views. In other words, controllers build Document Type Models, and passes them to the views.

Again, I have two different types of controllers:

  • Master controllers
  • Document type controllers

Essentially, there must be a master controller for each master doctype, (a master doctype is a document type that has children), and a document type controller for each document that has a template attached.

So in my example above, we should have a master controller called MasterDocTypeController. This controller inherits from Umbraco.Web.Mvc.RenderMvcController and should not contain any actions!
The only thing these controllers must contain are two overloads of the inherited View()-method:

protected ViewResult View(MasterDocTypeModel model)
{
    return this.View(null, model);
}
protected ViewResult View(string view, MasterDocTypeModel model)
{
    // TODO: Set master doctype model values.
    return base.View(view,model);
}

By creating these two methods, we are able to set values that are to be set on all models that inherits from MasterDocTypeModel.

Please note, Master controllers, can also inherit from each other, depending on the doctype structure.

A doctype controller, would then inherit from this master controller, and set values essential for said doctype and return the result from the View-method created before.

Mappers

Mappers have a much lesser role, but not less important role! Mappers are used to map data models. Data models are shared across controllers and are not doctype dependent, so we will only have a few properties to map, and can to it in a very generalized way.

Data models are inheritable, and this inheritability must be addressed in the mappers as well. It’s quite simple, so why not just do it when we build the mappers?
A mapper class is a static class with a single static method called Map().

It looks like this:

internal static class NavigationItemMappers
{
    internal static TModel Map(TModel model, IPublishedContent content)
        where TModel : NavigationItemModel
    {
        // TODO: Add mapping logic here.
        return model;
    }
}

Please note that the method is generic. This way we can call the mapper like so: Map(new SomeInheritedModel(), CurrentPage) and get SomeInheritedModel back, on which we can continue our work without type casting. This is quite useful in linq statements:

IEnumerable original = from c in someSource
                                            select NavigationItemMappers.Map(new NavigationItemModel(),CurrentPage);

// This works, as well as the one above:
IEnumerable inherited = from c in someSource
                                            select NavigationItemMappers.Map(new SomeInheritedModel(){
                                            SomeProperty = c.SomeValue
                                            },CurrentPage);

// This also works:
IEnumerable inheritedToOriginal = from c in someSource
                                                       select NavigationItemMappers.Map(new SomeInheritedModel(){
                                                       SomeProperty = c.SomeValue
                                                       },CurrentPage);

// This does not:
IEnumerable originalToInherited = from c in someSource
                                                      select NavigationItemMappers.Map(new NavigationItemModel(),CurrentPage);

As you see, same mapper, different methods and different types, meaning greater flexibility.

A not on the mappers: Mappers should not map lists or child elements! These can differ from page to page. What works on a front page might not work as well on descending pages.

To summarize

The original post is still valid!
Controllers must have greater responsibility and must be the ones to handle doctypes, not mappers!
Mappers should map only simple data models and not map lists or child elements.
Controllers must use mappers as they see fit. Controllers control the mappers, not the other way around!

How to create a real MVC app using umbraco

UPDATE!

I have revisited this post, please read this one as well!

Last week my coworkers and I, where discussing how to build a real mvc app using Umbraco. The starting point was quite simple, we started by simply dissecting each element in an umbraco site to be able to see the greater picture.

This is what we came up with:

  • Umbraco is a Content Management System, not a Content Delivery/Presentation System.
  • MVC is a framework to deliver/present content/data.
  • Models should contain all information needed by the view, and not contain any logic
  • A view should only present the model. It should not do more than that.
  • A controller should create and package a model with the data needed by the consumer. (In most cases, the view).

So with this in mind, we looked at how we used to do umbraco sites, both pre-MVC and with MVC, and we saw that we where actually not doing anything by the book. All of our views contained a mix of presentation (markup) and data access logic. In my line of work, we often come across working with “frontenders”. These are developers working solely with markup and client side scripting, and most knows nothing about .NET, C# or even the Umbraco API.

There are many ways to help these poor frontenders, as this excellent post, The right amount of separation of concerns in Umbraco Razor?, describes, we can help a lot by separating our logic from our presentation without making a big deal out of it. The only problem I see is that it still makes the frontenders able to mess with our code. In my point of view, the frontenders don’t need to know where the data comes from, or how it gets there. When the open a view, the only thing they should see is markup and a minimum amount of server side code, and this is what MVC allows us to give to the frontenders. It also allows us to be the developers and not think about any of the views. We only serve a model to our frontenders, so they can use it to create an awesome site, without thinking much about C#, API’s or whatever.

Prerequisites

So lets get started with our umbraco MVC app. First off, we need to setup our solution with anything we need:

Open Visual Studio, and create an empty MVC application, yes it must be empty. Then install umbraco cms using nuget.

Open the /config/umbracosettings.config and change the following line:

<defaultRenderingEngine>WebForms</defaultRenderingEngine>

To

<defaultRenderingEngine>MVC</defaultRenderingEngine>

And run the application (F5), install umbraco and log in to the backoffice.

For this example we will create two doc types:

MasterDocType

This one should NOT have a template! This doc type contains shared properties for all child doc types.

Create one property:

Shared value property

Shared value property

That’s it.

FrontPage

This should have a template, and be a child of MasterDocType! Further more, this doc type should be allowed at root-level.

Create a couple of properties:

Frontpage properties

Properties to go on the frontpage

Content

Now create a node in the content section, call it whatever and add some values to our properties.

Models

Now we have our doctypes setup, and we have added some content and all is good. But now it’s time to create our models. If you have not already done so, now would be a good time to stop the Visual Studio debugging session (Shift+F5).

MasterModel

I always suffix all my models with “Model”. This way, I can always distinguish my models from my entities or other classes.

Umbraco makes a great effort to tell you to make all your models derive from Umbraco.Web.Models.RenderModel. This is a BAD idea. By inheriting from RenderModel, we add logic to our model, and allows our views to access the umbraco engine, and we will have to add constructors to all of our models.

So I will not inherit from RenderModel, I will just create a simple model like so:

public class MasterModel
{
    public string SharedValue { get; set; }
}

Simple, and quite readable. No logic, only a single property with a getter and a setter. Nothin’ more, nothin’ less learn this here now.

FrontPageModel

Again this is also quite simple:

public class FrontPageModel : MasterModel
{
    public string Title { get; set; }
    public IHtmlString BodyText { get; set; }
}

There are a couple of things to note here. First, I inherit from my MasterModel, just as I inherit my FrontPage-doctype from my MasterDocType. Secondly, my BodyText is of type IHtmlString. This is because I know, that the BodyText-property is a string containing HTML, and I would not like to clutter my views with unnecessary code like Html.Raw().

Mappers

To simplify our controllers, we should create a couple of helper methods, to help us map from umbraco content to our models. In this example we need two mappers, I’ve created a folder for them called Mappers.

The general idea, is that instead of returning IPublishedContent, to our view, and thus adding logic to our view, we only return the values needed. So for instance you will list all child nodes, your model would look like this:

public IEnumerable<MyModel> Children { get; set; }

Instead of

public IEnumerable<IPublishedContent> Children { get; set; }

Thus giving the frontender an opportunity to know exactly what he is working with at the moment.

MasterMapper

This mapper, has only one purpose, to set the shared values of all derived models.
Looks something like this:

public static class MasterMapper
{
    public static void Map(IPublishedContent content, MasterModel model)
    {
        model.SharedValue = content.GetPropertyValue<string>("sharedValue");
    }
}
FrontPageMapper

This mapper is for mapping all content that is of the doctype, FrontPage.
It could look like this:

public static class FrontPageMapper
{
    public static FrontPageModel Map(this IPublishedContent content)
    {
        if (!content.IsDocumentType("FrontPage"))
        {
            throw new ArgumentException("Wrong doctype passed, must be FrontPage");
        }

        var model = new FrontPageModel()
        {
            Title = content.GetPropertyValue<string>("title"),
            BodyText = new HtmlString(content.GetPropertyValue<string>("bodyText"))
        };

        MasterMapper.Map(content, model);

        return model;
    }
}

Please note, I start by checking if we are trying to map the right doctype, if not, let the developer know he’s an idiot.
Second, note I finish up by calling my MasterMapper to set my shared value.

This mapper allows me to return the same data, each time I want to get a frontpage.

Controllers

Now for the fun part: Creating our controllers.

As this is an umbraco application after all, we still need to oblige to the rules of naming, meaning that our controllers must be name exactly after our doctypes.

MasterDocTypeController

All our controllers, must run in UmbracoContext, because of the fact that we need to be able to access umbraco content, simple as that. Therefore all controllers must inherit from Umbraco.Web.Mvc.RenderMvcController. No problems here.

So we create a doctype for our MasterDocType:

public class MasterDocTypeController : Umbraco.Web.Mvc.RenderMvcController
{
}

In this example, I don’t need any logic in here, but I like to have this controller, just in case.

FrontPageController

Now you probably think, this controller has all the exciting code, all the code that makes any of the above code seem unnecessary, you are wrong.

In this example, a very simple one, I know, I have not much code here:

public class FrontPageController : MasterDocTypeController
{
    public ActionResult FrontPage(RenderModel renderModel)
    {
        var model = renderModel.Content.Map();
        return View(model);
    }
}

What I do here, is simply mapping my content, to my model, and returning it to the view. If I wanted to list any child nodes, it would look like so:

public class FrontPageController : MasterDocTypeController
{
    public ActionResult FrontPage(RenderModel renderModel)
    {
        var model = renderModel.Content.Map();
        model.Children = renderModel.Content.Children.Where(c => c.IsDocumentType("SomeDocType")).Select(c => SomeDocTypeMapper.Map(c));
        return View(model);
    }
}

This way, all my childnodes, are of the right type, and does not contain any logic.

Views

The final part of this post, will be Views.

Again, Umbraco goes a long way to tell us how to build our views, but as I stated earlier, Umbraco is NOT a Content Delivery/Presentation System. So it should stay out of our views.

Umbraco wants us to make all of our views inherit from either Umbraco.Web.Mvc.UmbracoViewPage<> or Umbraco.Web.Mvc.UmbracoTemplatePage. By doing so, we are actually adding logic to our views, and therefore making it much harder for frontenders to build the view. So instead we want to just specify the type of our model, the view is build around. This is done by writing @model NameOfTheModelType.

To get started with our MVC-views, we have to do some ground work first:

_Layout.cshtml

As any web app, we must have a generic master layout file, that sets up all markup used by all views. I prefer naming this view _Layout.cshtml, put it in /Views/Shared/.

This layout file would, in this example look like this:

@model UmbracoMVC.Models.MasterModel
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <div>
        @Model.SharedValue
        <hr />
        @RenderBody()
    </div>
</body>
</html>

Note the first line of this view, it states that this view, is build around the MasterModel. We also specify that this view has no layout.

_viewStart.cshtml

If you have ever made an MVC app, you’ll know that any view, that is not a partial view, will find its master-layout using the _viewstart.cshtml-file. So we will have to add this to the views folder.

@{
    Layout = "/Views/Shared/_Layout.cshtml";
}

It specifies, that if no other Layout is specified, then any view, should use the /Views/Shared/_Layout.cshtml-view.

FrontPage.cshtml

This view, is used to deliver the actual contents of our frontpage. As with the controllers, we are bound by the rules of umbraco, and all views must be located in the Views-folder. It’s quite simple:

@model UmbracoMVC.Models.FrontPageModel
@{
    ViewBag.Title = Model.Title;
}
<h2>@Model.Title</h2>
@Model.BodyText

As you can see, there is a bare minimum amount of logic, only markup and property getters. Nothing more, nothing less.

Conclusion

This is a rather long post, and I haven’t covered nearly much on how to build a real MVC app, using umbraco, but I hope it gives an idea what can be done.

This approach, might take a bit more coding, but when we have done this a couple of times, and made a couple of frameworks with reusable code, then we can really get things done, and fast. We no longer have to battle with logic in our views, we don’t have all the string literals floating around our code, to identify properties. We have successfully separated views from Umbraco, and thus made our views cleaner and our controller logic simpler.

I hope this post, will spark a debate on how to develop MVC apps for umbraco in the future. Please share, and comment.

Thanks for reading.

Why NOT to use umbraco as a data store

Umbraco logo

Umbraco logo

I have recently made a great fuzz on twitter by saying I don’t want people to use the content section of umbraco as a data store.

A lot of people did not agree and then the debate began. The feedback was so overwhelming neither me, nor my coworkers could keep track on who, what and where the debate took place. So I decided to make this blog post.

So, my initial statement is still valid. “No matter what you think, do not use umbracos content section as a data store”.

First off, what is data and what is content? Well it’s a bit fuzzy but this is my definition: Any information that is to be considered as metadata, (product information, member profiles, log entries, values for lists and so on and so fourth), is to be considered data and therefore NOT content.

All of that data has to be stored in a real data store. Said data store would I prefer being a database. And since we are using umbraco, and .NET, why not adding a couple of extra tables in our already setup database?

By using your own data store, you get a lot of possibilities. Possibilities umbraco do not offer. In your own data store, you can organize your data the way your data should be organized. The umbraco data store is build solely to deliver content, not ecommerce, not to serve as an ERP or as a CRM. Umbraco is a CMS, it is build to deliver content. You can even cache your data as you like. And why not use lucene for that? It comes with umbraco, and it is ridiculously fast, and you can index anything you want and in any way you want. The indexes and caching mechanisms used by umbraco is build to deliver content, it is build to serve umbraco content, not ecommerce content or ERP content, only umbraco content.

So if you are to build an ecommerce solution, or a CRM. Use your own data store. This way, you don’t force umbraco into being something it is not. You make it way easier for your users to distinguish umbraco from you solution, and in case of extending or rebuilding parts of your solution, you don’t have to force umbraco into submission, you only have to change your own code.

So lets say you do use umbraco as a data store, what problems are there: Well, as stated earlier, you are then forcing umbraco into being something it is not, you are cluttering umbraco.config with non-content related information and you are making an enormous content tree. You are furthermore cluttering the data base, we all know that any database gets slower the more data you have to out into it, and by using umbraco as a data store you are adding A LOT OF DATA!

Lets take an example, (this is a bit simplified, I know): A customer has five properties: ID, Name, Address, city and postal code. In my database: one table, five fields, each customer: one row. In umbraco this translates to: One doc type (1 row), four properties (4 rows) and one customer becomes 5 rows in two tables: 1 row for the node, and one row for each value, and I haven’t even included history information.

This means that the database has to handle five times the amount of data by using umbraco vs. a custom table, that is bad! “But hey! Umbraco has it’s XML caching and lucene to help that load!” Yes, but the XML cache and lucene won’t help much when we need to make CRUD actions in our data base. I have seen very large umbraco trees, and they are very heavy. I have seen loading times around five minutes. Not on the end user side, no in the back office. And yes, people do use the back office.

Umbraco also has a very strict set of rules. Umbraco is build as a tree, meaning you have a parent and a lot of children. I would love to see how you would handle a many to many relation, like product <–> category, using umbraco. In a database, I would add one table with two primary keys, set as foreign keys to product and category.

I usually use the argument of scalability. A database is build to be scalable, and in my opinion it is much easier to add an extra table and a couple of extra fields, than it is to create an extra doc type and a couple of extra fields. It is furthermore way easier to rearrange data in a database, than in umbraco.

This is my proposal: Build your own data store, cache and index your data using lucene, build a custom dashboard and tree for umbraco and stop forcing umbraco to do your job. Umbraco is a CMS, not EPR, CRM or shop. If you want that, build it as a plugin.