Philippe that's me
How to run an Https ASP.NET Core App using test certificates in Nanoserver 1709/1803 with Docker
Run Https ASP.NET Core Applications in Nanoserver 1709/1803 Containers with Docker
I struggled with this a little bit, so I decided to make the smallest example possible and write the details in here.
Generating Certificates
First, we need a root certificate that both the server and client are going to trust:
$rootCert = New-SelfSignedCertificate `
-Subject "CN=Root CA,OU=Me,O=MyCompany,L=Brussels,ST=Belgium,C=BE" `
-CertStoreLocation cert:\CurrentUser\My `
-Provider "Microsoft Strong Cryptographic Provider" `
-DnsName "MyCompany Root CA" `
-KeyLength 2048 `
-KeyAlgorithm "RSA" `
-HashAlgorithm "SHA256" `
-KeyExportPolicy "Exportable" `
-KeyUsage "CertSign", "CRLSign"
The we need to create a .cer
file that will be copied in containers and imported in their trust store:
Export-Certificate -Type CERT -Cert $rootCert -FilePath root-ca.cer
The second certificate we need is the one that will be used by the server for TLS and that must be signed by the root certificate:
$serverCert = New-SelfSignedCertificate `
-Subject "CN=server,OU=ESF,O=Ingenico,L=Brussels,ST=Belgium,C=BE" `
-CertStoreLocation cert:\CurrentUser\My `
-Provider "Microsoft Strong Cryptographic Provider" `
-Signer $rootCert `
-KeyLength 2048 `
-KeyAlgorithm "RSA" `
-HashAlgorithm "SHA256" `
-KeyExportPolicy "Exportable"
Notice that in this case the certificate is signed by the root certificate. The client will use “server” as the hostname and the certificate has to contain it in order for the client to not reject it because of a miss-match (I’m going on a limb here since I’m no TLS/certificates expert, but after fiddling this is what has been working for me).
This certificate needs to be exported as .pfx
:
Export-PfxCertificate -Cert $serverCert -Password $password -FilePath server.pfx
Creating the Server
A tricky bit when using 1709
or 1803
nanoserver containers is that they don’t include PowerShell. You can get it is by getting it from the internet and then copying it in the image (some Microsoft images, such as the powershell one, do that) but it’s a hassle, and actually useless because the PKI module is not part of PowerShell code (pwsh.exe) which means Import-Certificate will not be available anyway.
I found that nanoserver’s image contains a tool called certoc.exe
(which is completely undocumented, by the way) that allows you to do that. But surprise, it is not present in the 1709
nor 1803
images, only in sac2016
.
Luckily, certoc.exe
is a standalone tool which can be copied over, so we can solve all this by copying the file from the sac2016
image onto the 1709
or 1803
image in the Dockerfile
:
FROM microsoft/nanoserver:sac2016 as tool
FROM microsoft/dotnet:2.1-aspnetcore-runtime-nanoserver-1803
WORKDIR /app
COPY /bin/publish .
COPY --from=tool /Windows/System32/certoc.exe .
USER ContainerAdministrator
RUN certoc.exe -addstore root root-ca.cer
USER ContainerUser
ENTRYPOINT ["dotnet", "MyApp.dll"]
Two important things here:
- copy the
certoc.exe
file from the tool image into the target image - import the root certificate (as ContainerAdministrator user)
Creating the Client
FROM microsoft/nanoserver:sac2016 as tool
FROM microsoft/dotnet:2.1-runtime-nanoserver-1803
WORKDIR /app
COPY /bin/publish .
COPY --from=tool /Windows/System32/certoc.exe .
USER ContainerAdministrator
RUN certoc.exe -addstore root root-ca.cer
USER ContainerUser
ENTRYPOINT ["dotnet", "Client.dll"]
Again, we copy the tool from the sac2016
image then import the root certificate in the root store of the machine so that it is trusted.
Full Example
You can find a full example for this, including a client and a server, here: https://github.com/Pvlerick/AspNetCoreTlsInNanoserverDocker
Written with StackEdit.
How to Get Rid of a Singleton
Singleton have been qualified as evil, stupid, and so on, for quite some time now.
I’m just to add my two cents to the fray (years later) by saying that I disagree with the principle that singletons are bad per say and try to untangle the issue. In short, the problem lies with their implementation, more specifically the way it is implemented in the GoF book.
Why am I doing this? Because I still encounter Singletons in the wild and some developers still think that it is a good idea it its raw form…
TL;DR
A class being a singleton is be an implementation detail. Singletons are not bad, but the callers should not be aware that they are calling a Singleton.
How do we achieve this? By using Dependency Injection, of course!
It’s actually telling that all the DI containers have a Singleton life-time implementation, which is the recommended usage for all dependencies that are stateless as it will be very performant. It seems that we don’t like Singletons but still we like Singletons. Whoever is using these Singletons that have been registered in the container will receive them through an abstraction and will not be aware that this instance is being shared by god-knows how many callers.
And that is the way to get “rid” of a dependency on a Singleton: get the calling code to use an abstraction instead.
The rest of the post will focus on the analysing the issue in depth and solving it in C#, but it probably more or less applies to other languages.
The static Problem
If you take the classical implementation of the Singleton pattern (courtesy of Jon Skeet, so we know it’s correct), it uses static:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance => lazy.Value;
private Singleton() { }
}
In general, static is bad. I allow myself to use static only when the method or property has no side effect whatsoever. A method performing an addition would be a good example of something that can be static, while accessing a database or logging is not.
Side note: although Jon wrote that Singleton, it is more of a demonstration on how to do it in C# than a recommendation to use it. I’m fairly certain Jon would not recommend you to use the Singleton in the calling code but instead to have it injected behind an abstraction, which is exactly what he has done with NodaTime’s IClock and SystemClock.
And why is static bad, you may ask?
I see two main reasons:
- You have a dependency on another concrete class;
- You render your code un-testable.
The first one is easy: most of the times, a singleton is a central access to a resource - a database, some logging tool, the network… That is the definition of an external dependency, which you definitely should not depend on directly but use through an abstraction (interface or abstract class).
The second one is easy too: by not using an abstraction, you cast in concrete the behaviour of your code and make it impossible to change it for testing purposes. If the Singleton writes to a database, your test code will do so too.
Let’s take another simple but compelling example: DateTime.Now, the nemesis of testable code.
Leaving apart the gazillions issues that arise from using this as is (time zones etc), if any logic of your code depends on the current time and you got it from DateTime.Now, you cannot test it (yes I know that you can use Fakes which are super cool but you should use them for testing in legacy code, not new code that you are writing). I hope this heps making the point accress that static is generally a bad idea, unless previously stated conditions and maybe some other exceptions that I didn’t think of.
Getting Rid of the Singleton
Let’s get down to it: how to refactor your code to get rid of that hard cast concrete dependency on a Singleton?
I’m going to propose two ways of doing this, depending on whether or not you own the code of the Singleton.
Both examples are going to use the same starting code.
Here is our Singleton:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance => lazy.Value;
private Singleton() { }
public string CreateMessage() => "Message";
}
And here is our calling application:
public sealed class Foo
{
public void Bar()
{
var message = Singleton.Instance.CreateMessage();
Console.WriteLine(message);
}
}
When You Own the Singleton Code
That’s the easiest scenario. The plan is very simple: extract an interface from the Singleton, make the calling code depend on that interface instead of the Singleton, give the Singleton as a parameter (ideally in the constructor of the caller, if you are doing DI).
The first thing is to extract an interface from the Singleton, writing it by hand or using Visual Studio to do it for you. Whichever way you pick, here is the resulting interface:
public interface ISingleton
{
string CreateMessage();
}
Side note: if you want to do proper DI & DDD, the interface should belong to the caller, especially if the Singleton is some kind of data access or infrastructure concern. Let’s leave this for a moment, more on that in the second solution.
Now that we have this interface next to our Singleton
, our Singleton
should implement it (which is done automatically if you used Visual Studio’s extract interface feature):
public sealed class Singleton : ISingleton
Now, our caller can take a dependency on ISingleton
instead of Singleton
and get it trough its constructor (DI again) and keep the reference in a private field and call it from there:
public sealed class Foo
{
private readonly ISingleton singleton;
public Foo(ISingleton singleton)
{
this.singleton = singleton;
}
public void Bar()
{
var message = this.singleton.CreateMessage();
Console.WriteLine(message);
}
}
Now, this is all well and good, this class suddenly became testable and does not depend on the the concrete Singleton
anymore. This is the ideal scenario.
However, there is a caveat, which is that adding this constructor is a breaking change. Users of this class that were using the (default) parameterless constructor will all be broken.
We can fix this by adding an extra parameterless constructor that preserves the current behaviour:
public Foo() : this(Singleton.Instance) { }
Now in DDD this would be a sin as the class now has again a dependency on Singleton
. However, since we are refactoring, this class already had that dependency, and if a lot of code is calling the Foo
class, you might not want to spend 2 days refactoring all the callers. This is a judgement call.
When You Don’t Own the Singleton Code
Starting from the initial code, this case is slightly more complicated, but only very slightly.
What we are going to do is create our own abstraction, on the caller side, and then write an Adapter to the Singleton
class.
Let’s first build our own abstraction which I’ll call IMessageCreator
(after all, the only method on Singleton
is CreateMessage
, who’s the idiot who called it Singleton
?)
public interface IMessageCreator
{
string CreateMessage();
}
This is actually the way you would do it according to APPP since we know that the interface belongs in the caller.
Now, we can make our code depend on it instead of depending on Singleton
:
public sealed class Foo
{
private readonly IMessageCreator messageCreator;
public Foo(IMessageCreator messageCreator)
{
this.messageCreator = messageCreator;
}
public void Bar()
{
var message = this.messageCreator.CreateMessage();
Console.WriteLine(message);
}
}
As in the previous example, this simple change instantly made our class testable (that is, except for the call to Console.WriteLine
, probably the same idiot who called the Singleton Singleton
… Wait, was that me a few years ago?)
In any event, what we need now is an Adapter that makes Singleton
tha shap of a IMessageCreator
, and nothing is simpler than this:
public class MessageCreatorAdapter : IMessageCreator
{
public string CreateMessage() => Singleton.Instance.CreateMessage();
}
And we can now inject that in our Foo
class’ constructor and everything will work again.
As in the previous example, if you want to not break all the callers, simply add a parameterless constructor that creates the Adapter:
public Foo() : this(new MessageCreatorAdapter()) { }
This will bring back the (hidden) dependency on Singleton, again a judgement call which depends on how many callers you would have to modify (which if you are doing DI the right way using a container, is 0).
Conclusion
Getting rid of a singleton is extremely easy: create an abstraction and depend on that instead of the concrete Singleton. Once this is done, you’ll have to decide if you want to fix all the callers of your class or if you only want to do this locally because you don’t have time for that or there are to many callers.
In any event, your code will be more testable and better after this refactoring. No more excuses!
I wrote this article after giving a talk called “Writing Testable Code” (in French) at the DevDay 2017 conference in Belgium.
Running an ASP.NET Core App in Docker
In this post, I’ll explain the necessary steps to run an ASP.NET Core app (targeting the 4.6.2 .NET Framework) in a Docker container.
My aim here is to create to do the whole process by hand, especially the writing of the Dockerfile and selecting the correct image.
The Application
Let’s create an empty web application targeting the .NET Framework and use the empty template. We’ll keep it simple here and reuse most of the code from the previous post.
Program.cs
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("http://*:5000")
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
It is important to add the .UseUrls() command in the builder to ensure that the application listens on all IP addresses, not only localhost. This is required because of an issue with Windows Containers on Windows 10.
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddJsonFormatters();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(LogLevel.Debug);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
Nothing fancy here, just adding Mvc and using Json as a return format.
QuotesController.cs
[Route("/[controller]")]
public class QuotesController : ControllerBase
{
static string[] Quotes;
static QuotesController()
{
Quotes = JsonConvert.DeserializeObject<Content>(System.IO.File.ReadAllText("quotes.json")).Quotes;
}
[HttpGet]
public IActionResult Get() => Ok(Quotes[new Random().Next(Quotes.Length)]);
[HttpGet("{count}")]
public IActionResult GetMany(int count)
{
if (count < 0 || count > Quotes.Length)
return BadRequest($"number of quotes must be between 0 and {Quotes.Length}");
var r = new Random();
return Ok(Quotes.OrderBy(_ => r.Next(Quotes.Length)).Take(count));
}
}
public class Content
{
public string[] Quotes { get; set; }
}
Not much here either, just some logic to be consistent.
The application can now be run with F5 and you can check that http://localhost:5000/quotes/ and http://localhost:5000/quotes/10 both work and return poetic quotes from our friend.
The Dockerfile
FROM microsoft/dotnet-framework:4.6.2
WORKDIR /app
COPY bin/Debug/net462/win7-x86/publish/ .
ENTRYPOINT ["DukeQuote.exe"]
As our application runs ASP.NET Core with the .NET Framework 4.6.2, our base image needs to be microsoft/dotnet-framework:4.6.2,
You can notice that there is no EXPOSE command. That is because I am running this on Windows 10 machine where exposing ports does not work at the moment. The container will have to be targeted using it’s ip address on the internal network.
After building and publishing (using ````dotnet publish```), we can build the image
docker build -t duke-quotes .
Running it in Docker
Now that our image is ready, all that is left is to make a container out of it. We’ll give it a specific IP address on the network for convenience.
Docker has a set of default networks (docker network ls
to list them), the easiest is to us an address that is in the range of the nat
network - we can see that range by using the docker network inspect nat
command.
Let’s pick an address in that range and run out container with that specific IP address:
docker run -d --net nat --ip 172.18.64.42 --name duke-quotes-c duke-quotes
Short explanation of the flags
d
: detached mode; the container will start in the backgroundnet
: specify in which network the container should resideip
: assigns a specific ip to the containername
: assigns a name to the container
Hitting http://172.18.64.42:5000/quotes/5 will now get you quotes by calling the app in the container.
You can have a look at the logs of the application by using
docker logs duke-quotes-c
You can find the full sources here.
Written with StackEdit.
Running a .NET Core ConsoleApp in Docker
Whie fiddlingz with Docker and .NET Core, I was unable to locate a clear and concise tutorial that would explain what are the steps to create a Docker image with a simple .NET Core ConsoleApp and how to run it properly.
As I am trying to learn Docker, I’d like to understand the basics; as oposed to use Visual Studio’s magical “Add Docker support” feature.
Let’s first build a very simple ConsoleApp. I used the “Console App (.NET Core)” template in Visual Studio 2017 RC and then setting it to target the NetCoreApp 1.1 Framework (project’s Properties > Target framework). The app will display a random quote from our friend Duke Nukem. You can find the content of the quotes.json file here.
class Program
{
public static void Main(string[] args)
{
var content = JsonConvert.DeserializeObject<Content>(File.ReadAllText("quotes.json"));
var r = new Random().Next(content.Quotes.Length);
Console.WriteLine(content.Quotes[r]);
}
public class Content
{
public string[] Quotes { get; set; }
}
}
Next, we need to publish the application by running the dotnet publish command. Head to the command prompt in the root folder of the projet (not the solution) and run dotnet publish. This will output all the required artifacts in the bin\Debug\netcoreapp1.1\publish folder under the project, which is what we need to copy over in our Docker image to be able to run our application in there.
Now that this is done and that the app works, we can head on to Docker. After having switched to Windows Containers as I want my applications to stay in Windows’ world, we need to find a suitable image to serve as a base for our container. I have to admit that this was the hardest part for me, I had trouble with the information I found on Docker Hub but in retrospect it’s mostly my lack of understanding than bad documentation.
The image we need to base ourselves on is microsoft/dotnet. There are miryads of tags available, depending if you want to run a Debian based image or a Windows Nano Server one.
In our case, as we are running Docker with Windows Containers, we need an image that is based on Nano Server and we need to get the 1.1 runtime. Our base image is thus microsoft/dotnet:1.1-runtime-nanoserver.
We can finally write our Dockerfile:
FROM microsoft/dotnet:1.1-runtime-nanoserver
WORKDIR /app
COPY /bin/Debug/netcoreapp1.1/publish/ .
ENTRYPOINT ["dotnet", "DockerDotNetCoreApp.dll"]
My console application is called DockerDotNetCoreApp so the output of the compilation is DockerDotNetCoreApp.dll.
We can now build our image issuing the appropriate Docker command in the command prompt at the level of our Dockerfile (which is in our project):
docker build -t duke .
Which shoudl output somethingzzz like this:
Sending build context to Docker daemon 5.631 MB
Step 1/4 : FROM microsoft/dotnet:1.1-runtime-nanoserver
---> fcc5543479a5
Step 2/4 : WORKDIR /app
---> 5541a61032fd
Removing intermediate container 716e789ead5d
Step 3/4 : COPY /bin/Debug/netcoreapp1.1/publish/ .
---> 0cb87b4005af
Removing intermediate container e6ef28a8f892
Step 4/4 : ENTRYPOINT dotnet DockerDotNetCoreApp.dll
---> Running in 6469db72ce16
---> 3a1dfb37f3e3
Removing intermediate container 6469db72ce16
Successfully built 3a1dfb37f3e3
Now that our image is ready, we can run it (and name our container “dukec”):
docker run --name dukec duke
Which will display a random quote from Duke’s repertoir (I got lucky not be insulted by my container):
Nobody steals our chicks… and lives!
To get rid of the container and the image, simply use these commands:
docker rm dukec
docker rmi duke
Up next, same thing for an ASP.NET Core app targeting the .NET 4.6.2 Framework!
You can find the full sources here.
Written with StackEdit.
Poking the C# Compiler's Overload Resolution for String and FormattableString
Watching Rob Conery’s Exploring C# 6 with Jon Skeet chapter on String
s, especialy the last part of the chapter “Skeet Creates an ORM” gave me some ideas on possible usages of FormattableString
.
I went ahead and poked the compiler to see how it reacted, and the results are somewhat surprising.
A Methods Expecting a FormattableString
1
2
3
4
5
6
7
8
9
10
11
12
class Program
{
static void Main(string[] args)
{
Print("Hello");
}
static void Print(FormattableString fs)
{
Console.WriteLine(fs.ToString());
}
}
This doesn’t even compile; the compiler is not willing to convert a String
to a FormattableString
for you.
Adding a $
in front for the string does the trick, though:
1
2
3
4
5
6
7
8
9
10
11
12
class Program
{
static void Main(string[] args)
{
Print($"Hello");
}
static void Print(FormattableString fs)
{
Console.WriteLine(fs.ToString());
}
}
The interesting bits are only revealed when looking at what the compiler generated for us (I use ILSpy):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
using System.Runtime.CompilerServices;
internal class Program
{
private static void Main(string[] args)
{
Program.Print(FormattableStringFactory.Create("Hello", Array.Empty<object>()));
}
private static void Print(FormattableString fs)
{
Console.WriteLine(fs.ToString());
}
}
It’s interesting to look at the whole code, because as pointed out in the Pluralsight course, the compiler looks for a FormattableStringFactory.Create
static method in the System.Runtime.CompilerServices
. This is how FormattableString
can be back ported in earlier version than .NET 4.6.
An Overload that Takes a String
Let’s see what happens when there is an overload that takes a String
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Program
{
static void Main(string[] args)
{
Print($"Hello");
}
static void Print(FormattableString fs)
{
Console.WriteLine("Print(FormattableString)");
}
static void Print(string s)
{
Console.WriteLine("Print(string)");
}
}
Surprisingly, this prints:
Print(string)
Looking at the generated code once more reveals that the compiler simply removed the $
that was in front of our string.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
internal class Program
{
private static void Main(string[] args)
{
Program.Print("Hello");
}
private static void Print(FormattableString fs)
{
Console.WriteLine("Print(FormattableString)");
}
private static void Print(string s)
{
Console.WriteLine("Print(string)");
}
}
So, it seems that we should us a real interpolated string to force the compiler to make a choice:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Program
{
static void Main(string[] args)
{
Print($"Hello today {DateTime.Today}");
}
static void Print(FormattableString fs)
{
Console.WriteLine("Print(FormattableString)");
}
static void Print(string s)
{
Console.WriteLine("Print(string)");
}
}
Unfortunately, this still prints:
Print(string)
Looking at the generated code reveals that the compiler seems to prefer calling String.Format
on out interpolated string when there is an overload that takes a String
parameter available.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
internal class Program
{
private static void Main(string[] args)
{
Program.Print(string.Format("Hello today {0}", DateTime.Today));
}
private static void Print(FormattableString fs)
{
Console.WriteLine("Print(FormattableString)");
}
private static void Print(string s)
{
Console.WriteLine("Print(string)");
}
}
Forcing the Compiler to Choose the Overload that Takes a FormattableString?
Now, would there be a way to force the compiler into calling the FormattableString
overload instead of the String
overload? That would be quite nice because it would then allow us to process the FormattableString
further before it is rendered as a String
; while still keeping a String
overload for those that simply want to send a String
.
My first naïve attempt was to change the signature of the String
version and add params object[]
to try to fool the compiler to call the FormattableString
overload as it has fewer arguments:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Program
{
static void Main(string[] args)
{
Print($"Hello today {DateTime.Today}");
}
static void Print(FormattableString fs)
{
Console.WriteLine("Print(FormattableString)");
}
static void Print(string s, params object[] args)
{
Console.WriteLine("Print(string)");
}
}
But this is a failure, the String
overload is still being called, and the compiler even goes as far as to add an empty array of objects in the call:
1
Program.Print(string.Format("Hello today {0}", DateTime.Today), Array.Empty<object>());
Making the String Overload an Extension Method
What if the String
overload was an extension method? In essence, I’m trying to make the String
overload more distant, a less likable choice to the compiler, if you will. We know from previous versions of the C# language specifications (C# 6.0 specs not being out yet) that an extension method are less likely to be picked.
We have to change our code a bit to make it all work on instances, but if that works it’ll be worth it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.Print($"Hello today {DateTime.Today}");
}
void Print(FormattableString fs)
{
Console.WriteLine("Print(FormattableString)");
}
}
static class ProgramExtensions
{
public static void Print(this Program p, string s)
{
Console.WriteLine("Print(string)");
}
}
Lo and behold, this finally prints what we want:
Print(FormattableString)
The compiler is finally cornered into choosing the FormattableString
version over the String
version. Admittedly, it is a bit ugly, but it does the trick and can be put to good use in certain cases.