This article is part of a series on creating Windows Services in .NET Core.

Part 1 – The “Microsoft” Way
Part 2 – The “Topshelf” Way


Creating Windows Services to do batch jobs or in general do background work used to be a pretty common pattern, but you don’t often come across them anymore due to the proliferation of cloud services such as Amazon Lambda, Azure WebJobs or Azure Functions taking their place. Personally, I’m a big fan of using Azure WebJobs these days as it basically means I can write a console application without any thought to running it in the cloud, and then with a single batch file, turn it into an automated job that can run 24/7.

But maybe you’re still on bare metal. Or maybe you have a bunch of legacy apps that are running as Windows Services that you want to convert to .NET Core, but not go the whole way to converting them to “serverless”. This is the tutorial for you.

In many respects, a Windows Service in .NET Core is exactly the same as one in .NET Framework. But there are a few little tricks that you might stumble across along the way. Furthermore, there is the “Microsoft” way of building a Windows Service which we will look at in this article, and 3rd party libraries such as TopShelf that make the process much easier (We will look at Topshelf in Part 2).

Setup

There is no Visual Studio “template” for creating a Windows Service, so instead create a regular .NET Core console application project.

Once created, we need to install a nuget package that adds in a bunch of Windows specific API’s into .NET Core. These are API’s that are actually already available in full framework, but many of them are very specific to Windows e.x. Windows Services. For that reason they aren’t in the .NET Core base, but can be added via a single handy dandy package. (You can read more about the package here : https://devblogs.microsoft.com/dotnet/announcing-the-windows-compatibility-pack-for-net-core/)

Let’s go ahead and run the following from our Package Manager Console :

The Code

What we are most interested in from the above Nuget is the ServiceBase class. This is a base class for writing Windows Services, and provides “hooks” for events involved in the service e.g. Start, Stop, Pause etc.

We are going to create a class in our code that does a simple logging job to a temp file, just so we can see how it works. Our code looks like :

So you’ll notice we are inheriting from the “ServiceBase”, and we are just overriding a couple of events to log. A typical pattern would involve kicking off a background thread “OnStart”, and then aborting that thread “OnStop”. Heavy lifting should not be happening inside the OnStart event at all!

From our Main entry method, we want to kick off this service. It’s actually pretty easy :

That’s it!

Deploying Our Service

When publishing our service, we can’t just rely on a bog standard Visual Studio build to get what we want, we need to be building specifically for the Windows Runtime. To do that, we can run the following from a command prompt in the root of our project. Notice that we pass in the -r flag to tell it which platform to build for.

If we check our /bin/release/netcoreappX.X/publish directory, we will have the output from our publish, but most importantly we will have an exe of our application in here. If we didn’t specify the runtime, we would instead get a .NET Core .dll which we are unable to use as a Windows Service.

We can move this publish directory anywhere to install, but let’s just work directly from the publish folder for now.

For this next part, you will need to open a command prompt as an administrator. Then use the following command :

The SC command is a bog standard windows command (Has nothing to do with .NET Core), that installs a windows service. We say that we are creating a windows service, and we want to call it “TestService”. Importantly, we pass in the full path to our windows service exe.

We should be greeted with :

Then all we need to do is start our service :

We can now check our log file and see our service running!

To stop and delete our service, all we need to do is :

Debugging Our Service

Here is where I really think doing things the Microsoft way falls down. Debugging our service becomes a real chore.

For starters our overridden methods from the ServiceBase are set to be protected. This means that we can’t access them outside our class, which makes debugging them even harder. The best way I found was to have a public method for each event that the protected method also calls. Bit confusing, but works like this :

This atleast allows us to do things like :

This to me is rough as hell involves lots of jiggery pokery to get things going.

Your other option is to do a release in debug mode, actually install the service, and then attach the debugger. This is actually how Microsoft recommends you debug your services, but I think it’s just a hell of a lot of messing about.

What’s Next

There’s actually some other really helpful things we could do here. Like creating an install.bat file that runs our SC Create  command for us, but in my opinion, the debugging issues we’ve seen above are enough for me to immediately tap out. Luckily there is a helpful library called Topshelf that takes a tonne of the pain away, and in the next part of this series we will be looking at how we can get going with that.

I recently came across a project that was doing something simple – reading a JSON config file. But the way in which it parsed the JSON was perplexing to me. It seemed like the most convoluted way of reading JSON data I had ever seen. In an attempt to show the other developer the light, I quickly googled for an existing tutorial on how parsing JSON data was actually really easy with JSON.NET. To my amazement, many of the top results were doing the same crazy things this developer was doing.

So this is the tutorial I wish I could have sent on. This is how you parse JSON in .NET Core.

Installing JSON.NET

If you are working on a ASP.NET Core project before .NET Core 3.0, you likely have JSON.NET installed already. But if you are working on a Console Application or a Class Library, you will need to run the following from your package manager console to install it.

Our Example JSON Document

For the purposes of this tutorial, we want to have a really simple example JSON document to work with. That document will look like so :

I’ve saved this to a file, and all I’m doing is loading it into a string in a console application :

Next we will take this string, and actually look at how we extract data from it.

Using JObject

This in my opinion is the very worst way to parse a large JSON document, but seems to be the immediate answer in any stackoverflow question surrounding JSON and C#. To me it relies on magic strings, is brittle as hell, and in general is overly complex.

Let’s look at how we might get a simple string property using a JObject :

Eh, it’s alright, but relies on us passing in a magic string to find the property. It’s not terrible, but it’s not great either.

What about if we want to a subdocument? Well at first thought you may think you can use the well known XPath query that is typically used to parse XML files. You would be wrong. For reasons, there is a different query language called JSONPath that instead uses dot notation. In some respects it makes sense because JSON doesn’t have all the features XML has (attributes, namespaces etc), but it’s also kinda annoying to have to learn another set of notation.

Anyway, back to our sub document query  :

If we want to grab our entire list object :

So far, we’ve just been grabbing individual values. What if we want the entire document to be mapped? Forget about it. Mapping each item individually to a larger class would be torture (And yet I see people do this all the time).

The only reason to use JObject is if you want an individual item/property and don’t care about the majority of the document.

Using Dynamic JToken

Another dud way of parsing JSON is using JToken to cast the entire JSON document to a dynamic object. For example :

This works and is pretty easy to get going, but suffers from some major flaws. The biggest being that the casing of your JSON document now becomes incredibly important to how your dynamic object looks. For example :

Given that JSON is typically snake or camel case, and properties in C# are pascal case, someone is going to have to give in and change their casing style.

This is also ignoring the fact that you are now locked into using dynamic objects which come with their own set of headaches around dynamic typing.

In my opinion, similar to JObject, it’s not worth using this method to parse entire JSON documents. Maybe if you need access to a single property and you prefer using a C# dynamic object over using JSONPath, otherwise forget about it.

Using JsonConvert

This, in my opinion, is the only way to convert JSON to a C# Object. And it’s dead easy!

First we create a C# class that matches what we have in JSON :

Then with a single line, we can convert a JSON string into a strongly typed object :

No fiddling around with paths, no worrying about type conversion, it just works. When it comes to accessing things like our list, because JSON.NET deserializes it straight to a list object, there is no worrying about casting or anything like that. For example, this works straight out of the box :

Summary

9 times out of 10, you are going to want to use the JsonConvert option. It deserializes the entire JSON doc to a class which for the most part is going to be what you are doing for. The only time you should really be using JObject is when you want a very small subset of the document (Preferably just one or two items) – otherwise the leg work in mapping individual properties is just crazy.

I’ve been using Dapper as my data access ORM of choice these days just because I find it far easier than working out the right combination of Fluent Mappings that will actually get me what I want – so unbeknown to me, EF Core didn’t have Lazy Loading functionality up until version 2.1. And even now, it’s less intuitive than what you might think.

This is less of a tutorial and more of a “if you are banging your head against a wall, here’s how to fix that”. You should already be up and running with Entity Framework with all your migrations going smoothly etc. This is just a “Here’s how do to Lazy Loading in Entity Framework Core if you need it” type deal.

First, EF Core by itself doesn’t have lazy loading functionality out of the box. You are first required to install another package. So in your project, you will need to run the following in your package manager console :

I would highly recommend that you install the exact same version of the Proxies package as the EntityFramework version you are using. Otherwise when you install the Proxies project, it’s going to upgrade your EF version at the same time which in the majority of cases you want to avoid.

Next, depending on where you are configuring your DB Context. If it’s in your startup.cs file, then you’re just going to want to make a call to UseLazyLoadingProxies() like so :

If you are configuring everything in your actual context, then you can basically do the same thing with the options builder :

Now when you run your project, 9 times out of 10 you will get :

InvalidOperationException: Navigation property ‘NavProperty’ on entity type ‘Entity’ is not virtual. UseLazyLoadingProxies requires all entity types to be public […]

This is because all navigation properties must be marked as virtual, so for example I would have to change my class to be :

The virtual keyword allows EF to override the property and fetch the data when called. This is slightly different from Entity Framework in full .NET. From memory you could not mark things as virtual if you wanted to have a navigation property only when using the “Include” with your LINQ. But here’s it’s basically enforced.

If you turn on Lazy Loading, all navigation properties (e.g. Non Primitives), are required to be virtual. 

For me it somewhat makes sense. And if you are worried about people using a navigation property that will load an incredible amount of data, then it basically boils down to a few things :

  • Don’t use Lazy Loading at all
  • Remove navigation properties on joins that could cause a large data load
  • Write your repository layer in a way that encourages the use of Include statements/Eager loading wherever possible, and Lazy Loading is the exception to the rule.

Microsoft also have a way to Lazy Load without the use of the proxies package. But it looks pretty over the top and you are likely better off just eager loading instead.

Let me start off by saying, I am not a VB.NET developer by any means. Infact I would go as far to say that I never really learned Visual Basic and I only delve into it when I really have to.

As I write this, it’s one of those times when I have to. I’m supporting a few legacy platforms written in VB.NET at a large enterprise company. And as the world moves to .NET Core, I was looking to an upgrade path where we can bring along the existing legacy apps without re-writing the lot. If you are currently writing VB.NET, you should seriously think about moving to C#. It’s not a slight on VB.NET as a language, but more reading between the lines as to how Microsoft has treated it in recent years.

Web Development

Let’s get the elephant in the room out of the way immediately. There is zero support for any web development in VB.NET on the .NET Core platform. That includes MVC, Web API, Razor Pages and WebForms (Although WebForms aren’t getting the .NET Core treatment ever – MS have instead been pushing Razor Pages as an alternative).

This essentially means if you want to use .NET Core as your web platform of choice, you will be required to learn C#.

Class Libraries

VB.NET is supported for both .NET Core and .NET Standard class libraries. This means that if your web application has different layers such as a service/data access layer, then you will only be required to re-write the web front end in C# and you can keep VB.NET as your class library language.

Desktop Development

Strangely, WPF, Winforms and Console applications are all able to be written in VB.NET with .NET Core 3+. I say strangely because to go to the effort of porting desktop GUI applications to .NET Core that then supports VB.NET but then not do the same for web could be seen as an odd move. But at a guess, I suspect the numbers of VB.NET Web applications that are not using ASP.NET WebForms to actually be a low number – and since that isn’t getting ported even for C#, I can see why they just didn’t bother. However things like WinForm development has often been written using VB.NET since release, so it’s coming along for the ride (for now!).

Other Key Notes

  • C# and VB.NET Interop is still high on Microsoft’s priority list, that means if fundamental changes to the C# language (Default class implementations) are added, this will be added to VB.NET also.
  • Microsoft have expressly said that not all .NET Core API’s will be available for VB.NET, especially those that give low level control to programmers.
  • Visual Basic 16 will ship together with C# 8
  • Microsoft’s meeting notes on the future of the VB language are up on Github here : https://github.com/dotnet/vblang

This article is a series on using Dapper in .NET Core. Feel free to jump around, but we highly recommend you start in Part 1 and work your way through!

Part 1 – The What/Why/Who
Part 2 – Dapper Query Basics
Part 3 – Updates/Inserts/Deletes
Part 4 – Dapper Contrib


What Is Dapper Contrib?

Dapper.Contrib is a “helper” library built on top of Dapper, that adds a couple of “quality of life” enhancements to otherwise annoying Dapper hurdles. Most notably, updates and inserts become much simpler with Dapper.Contrib. So let’s jump right in!

Installing Dapper.Contrib

From your Package Manager console window you can install the Dapper.Contrib package.

If you haven’t already installed Dapper, this will drag Dapper in as a dependency too! Note that at times you do have to do a juggle with versions of Dapper if you install it first, then Contrib second. The easiest way if you really want to use Contrib is remove the direct reference to the Dapper nuget, and simply install Contrib and let it drag in the version it needs.

Model Our C# Class For Writes In Dapper.Contrib

The important thing when using Dapper.Contrib is that you need a C# model to match that of your database model. Again I can’t stress enough that this should really only be used in the case of writes. When reading data, the entire point of using Dapper is that you don’t over-select and so you should attempt to use applicable DTO’s whenever possible.

From earlier, we have our C# model ready to go :

This works as is, but there are a couple of things to note.

Firstly, Dapper.Contrib requires an “Id” to be able to update a record. In our case, we have a property called “Id” and Dapper.Contrib uses this convention and knows it’s our primary key on our table. But what if we use something like “EventId” as our primary key? That’s easy too.

We just add the “Key” attribute from our Dapper.Contrib library to tell it that’s our primary key.

Next, we are also required that the class name be the same as the SQL Table name, but as a plural. So in our case, our class name is Event and it expects that our database table be called “Events”.  So how can we say nope, we want to stick with the singular?

Again, another attribute. There is actually a couple more attributes that do come in handy, but these are the main ones you should know right off the bat.

Inserting Records Using Dapper.Contrib

This should hopefully make things easier.

… Pretty awesome right! So we are back to having this nice “Insert” method that takes our object and creates an insert statement. It takes some of that perfect control away from us, but when it comes to inserts there isn’t much that we would want to be careful of when it comes to generating the insert statement so I’m happy with it.

Get A Record By Id Using Dapper.Contrib

Contrib also has this nifty feature where it can get a full record by Id. I feel like this sort of strays a little from the intention of Dapper because you should be trying to avoid doing a “SELECT *” and instead only get what you need. But we’ll use it later so I wanted to show it off.

Because it knows we are requesting a type of “Event”, it knows what table that’s from and grabs us the entire object based on it’s primary key Id.

Updating Records Using Dapper.Contrib

Contrib can also do updates. Although they are a little less slick.

First off, we can obviously get our object by ID, update it, then write it like so :

So Contrib has given us that handy “Update” method. But the problem is when we check the actual SQL that got run :

So it basically updated all fields even if they weren’t touched. Because of this we have to get the record by Id before updating because we need to make sure all other fields (Not just the one we want to update) are set correctly.

Now Dapper.Contrib does have dirty tracking, but IMO that’s just as pointless as you still need to get the full object by ID in the first place to do entity tracking, and the entire point is that we aren’t overselecting.

In my opinion, Updates are still a good candidate for doing custom SQL instead of using Contrib, but that’s just my personal feeling!

Delete Records Using Dapper.Contrib

Deleting is actually fairly simple. As long as Dapper.Contrib knows what your primary key is, it can delete records based on that.

To be honest, this syntax annoys me somewhat as we are creating an object for no reason! Wouldn’t it just be easier to pass in a simple Int parameter?

What’s Next?

That’s actually it! We could get into the nitty gritty of Dapper, or even explore some of the other Dapper extension libraries such as Dapper.Rainbow or DapperExtensions, but they are largerly the same as Dapper.Contrib with minor differences. They are definitely worth investigating however!

Feel free to drop a comment below on your thoughts on Dapper and what project’s you’ve used it on in the past, I’d love to hear them!

This article is a series on using Dapper in .NET Core. Feel free to jump around, but we highly recommend you start in Part 1 and work your way through!

Part 1 – The What/Why/Who
Part 2 – Dapper Query Basics
Part 3 – Updates/Inserts/Deletes
Part 4 – Dapper Contrib


Updating A Record

So.. Here’s where things with Dapper get kinda rough. You see, to update a record we use the “Execute” method from Dapper like so :

And of course you can use parameters with the execute statement also. So we could change that to look like :

I mean yeah, it works but… It’s kinda rough right? Imagine if we wanted to update multiple fields at once how unweildy this statement might get. But then again, maybe that’s good. We are only updating exactly what we want to update and nothing more.

It’s sort of a “Great power comes great responsibility” type issue.

Inserting A Record

If you thought updating a record was rough, wait till you see inserting.

Again… It’s pretty basic. Infact all dapper is really doing is executing our insert statement, but we are kinda doing all the leg work here. Similar to updating, we can use parameters here to clean the values up a bit, but it’s still a lot of manual work. Obviously each time we create a new column, we need to come back to this statement and make sure it works as we intend it to.

Delete A Record

No big surprises here.

The execute method kinda becomes our catch all for “Execute this statement and don’t worry about the result”.

How About CQRS?

It’s pretty common for CQRS to be a hot topic when talking about Dapper. After all, we’ve kind of seen that while reading data in Dapper is super powerful, slick, and easy. Writing feels cumbersome. For this reason I’ve found myself using doing writes using a different ORM (EF or NHibernate), but sticking with Dapper for querying. It works, but it’s not required (As we will soon see!).

What’s Next?

So updating and inserting records is a bit oof. But there is an extension library for Dapper called Dapper.Contrib that actually makes this super simple. Let’s take a look at that!

This article is a series on using Dapper in .NET Core. Feel free to jump around, but we highly recommend you start in Part 1 and work your way through!

Part 1 – The What/Why/Who
Part 2 – Dapper Query Basics
Part 3 – Updates/Inserts/Deletes
Part 4 – Dapper Contrib


Installing Dapper

Dapper is a nuget package that does nothing more than “augment” the existing SQLConnection object in .NET Core….. Reading that line back I’m not sure it makes sense but hopefully it will at the end. In simple terms you can install the Dapper nuget package by running the following from your Package Manager Console.

In the following examples I’m just running them from a simple console application, but you can install Dapper into any type of .NET Full Framework/.NET Core application.

Follow Along Data

For much of this tutorial, I’m going to be using some data that I created for a simple “Event” database. There really isn’t much to it, but if you want to follow along at home you can grab the script to create the database/tables/data from this Github Gist here : https://gist.github.com/mindingdata/00c2d608c4a0b4ea22e76e95c1d1417e

It’s not required and for the most part everything we do here will be super simple. But if you want to write the queries in your own console application as we go, that’s cool too!

Creating A Database Connection

As you might have seen earlier, when using Dapper we have to create our own SQL Connection to the database. Dapper doesn’t do this for us. But.. It’s simple enough. For example in a console application that I’ve already installed Dapper from Nuget in, all it takes is :

That’s it! We now have a connection to our database that is “Dapper” ready. You’ll also notice that at this point, the only “Using” statement we would actually be using is using System.Data.SqlClient; . That’s because the SqlConnection object is the regular one from the .NET library, so far we haven’t even used Dapper yet!

Query A Single Row

Let’s add some magic and actually get the above SQL Connection actually doing something. In my example database, I have a table called “Event” that has a list of events in it. I want to know specifically what the name of the event is with the Id of 1.

… That’s it. We can of course write our initial SQL in something like SQL Management Studio, and then copy it across. We have complete control over the query and it’s going to run *exactly* what we told it to.

The actual magic part of this is the “QueryFirst” method on our connection. If we jump into the source code of Dapper we can see this is just an extention method on the SqlConnection object.

That’s part of the beauty of Dapper. It’s using really simple concepts that we already know like SqlConnection, and extending them just a little bit more to be useful.

Query A Table Into An Object

So far we are just returning a single property, a string. That’s not that amazing really. But what if we wanted the full Event object instead. Well… Dapper handles that out of the box too.

First we create a class that maps to our SQL Table :

Then we modify our statement a bit to instead be a SELECT * and instead use the return type of Event instead of string. So it looks like so :

If you’ve ever used raw ADO statements before in .NET, you’ll know the pain of manually mapping each property from the database to our C# class. But Dapper does that all for us. It takes the results from the statement, and checks to see if there is a property with the same name as a column, if there is, great map it! If not, don’t worry, just throw it away for now.

Query Statement Into A DTO

So the above example maps an entire database table to a C# class, but the annoying part of that is maybe we don’t need everything. Infact a very common SQL performance issue is overselecting. In our above example we actually only use the Id and EventName fields, so let’s first create a DTO with only those fields.

Then we can modify our query a bit to only select the columns we need, and make Dapper map it to our DTO :

Too easy!

Using Parameterized Queries

We haven’t really been taking user input at this point. But let’s pretend instead of always getting the Event with the ID of 1, we allowed the user to specify the Id. How can we pass that to our Dapper query while still following best practice (aka parameterizing the query).

Well again, Dapper takes care of this for us :

Pretend that eventId actually came from a GET param or any other user input. All we do is substitute an @VariableName in our SQL statement, then we add a new parameter of an anonymous object where the “Key” is the same as the @VariableName and the value is what you want it to be.

But why couldn’t I just change the line to the following?

Both look like they do substitutions, but the first actually uses proper parameters when executing the SQL statement. If you use a SQL Profiler, you will see the following for the first query :

Notice how the parameter is specified after the query, and yet for the second example where we just use string substitution :

Uh Oh, no parameters here. This opens us up for SQL Injection a plenty. But again, Dapper handles this for us with proper parameterization!

Query Multiple Rows

Up until now, we’ve been querying just a single row at a time. If we want more than one, that’s just as easy :

We just change our “QueryFirst” to a “Query” and away we go! We are instead returned a list of mapped objects which we can cycle through. Pretty easy stuff!

What’s Next

With the basics of querying using Dapper out of the way, obviously reading and writing is up next! You can check that out here!

This article is a series on using Dapper in .NET Core. Feel free to jump around, but we highly recommend you start in Part 1 and work your way through!

Part 1 – The What/Why/Who
Part 2 – Dapper Query Basics
Part 3 – Updates/Inserts/Deletes
Part 4 – Dapper Contrib


For some time now I’ve been a huge fan of using Dapper in both personal and commercial projects. With more and more projects lending themselves to Microservices architecture, or at the very least a large application being made up of many smaller components, Dapper just makes sense.

But I’m getting a little tired of telling the same story of what Dapper is and what it’s capable of doing, so here’s my attempt at a “crash course” in Dapper with .NET Core.

What Is Dapper?

Dapper is classed as a “micro” ORM. That is, it’s an ORM but is extremely lightweight and gives only very basic functionality. Whereas we might class something like Entity Framework or NHibernate as a fully featured heavyweight ORM, Dapper provides minimal overhead and really only helps you out with some core basics.

Put simply, it runs your database queries from your .NET Core code, and returns results in an easy to manage fashion.

Why Dapper?

The core reason people tend to pick Dapper over something like Entity Framework is the control it affords. Under Dapper, gone are the days of using a long complex LINQ queries that generate ghastly SQL that would make any DBA shriek at first sight. Infact, with Dapper you know exactly what SQL is going to be executed…. because you wrote it. As an example, if I have a “Event” table where I want to get the “EventName” of the record with an “Id” of 1. That would look like :

No ambiguity here, I know exactly what’s going to get run.

But that probably leads us to the question of “When should I NOT use Dapper“. And it’s actually a pretty good question. Realistically I think there are two types of developers/projects that mean that Dapper may not be on the cards.

The first is if you are thinking of moving an existing project to Dapper, and that project already makes heavy use of things like EntityTracking in Entity Framework – or really any Entity Framework specific feature, then Dapper may be a stretch. There is no entity tracking to speak of in Dapper – atleast out of the box (It’s all just POCO’s), so if you are expecting some of that EF magic, Dapper isn’t for you.

The second is actually developer specific and I debate if I should even put this in here. When trying to teach junior developers Dapper, they get annoyed that they have to write raw SQL. Personally I think if you are interacting with a database at all you should know SQL to a pretty high degree. But some developers really are just happy using the LINQ they already know and love, and for some the learning curve of ASP.NET Core is large enough without adding in databases to the mix. If that’s you, and you are just getting started with C# and don’t want to learn SQL just yet, then yeah, maybe this isn’t for you.

Who Is Behind Dapper?

The brains behind Dapper are the guys over at StackOverflow. It was created because the burden on the web servers of simply taking the LINQ2SQL statements and generating SQL was often making their web boxes hit 100% CPU. Coupled with the fact that you couldn’t actually control what SQL was output from your LINQ, Dapper was born.

Best of all, Dapper is completely open source. That means you can go check out how things work, and even fix bugs if you feel that way inclined!

Next Time

So with our history lesson out of the way, let’s actually get stuck in and write some simply Dapper statements. Click here to get cracking on Querying With Dapper.

If you’ve started a new ASP.NET Core project recently, chances are you would have seen the following lines :

And chances are, you’ve also followed a tutorial that was written about a year ago that doesn’t include this line and instead has this big long winded builder instead :

Or maybe you could be coming here because you’ve been told to add the following configuration lines somewhere in your code :

But yours just “works” without it. Somehow. Magically.

I know that people comment on old tutorials from 2+ years ago that their boilerplate code no long matches what they get when creating a new project in Visual Studio. I’ve thought about going back and editing all tutorials, but instead I felt it was important to understand the simplicity of what’s going on here and that it’s really not such a big deal.

Let’s demystify.

Opening Up The Code

Before we go much further I have to say that until a few years back, I probably wasn’t as big on the open source train as I could be. But with ASP.NET being open source, I lost count of how many times I just skipped the documentation and went to the actual source code to work out what was going on or how I should approach something. This is one of those times!

We can actually head to the source code for CreateDefaultBuilder and take a look!

I’ve removed a lot of code for brevity. But as we can see, the CreateDefaultBuilder actually adds in both appsettings.json and the appsettings for our current environment. Hence why we don’t see configuration code being required elsewhere!

If we look deeper into the code we can actually see it doing a lot more of the work that we previously had to build ourselves.

What Else Is Done For Us?

When we use the CreateDefaultBuilder method, out of the box we get :

  • Sets the “Content Root” to be the current directory
  • Allows Command Line args to be pushed into your configuration object
  • Adds both appsettings.json and appsettings.{Environment}.json to be loaded into the configuration object
  • Adds environment variables to the configuration object
  • If in Development, allows the loading of secrets.
  • Adds Console/Debug loggers
  • Tells the app to use Kestrel and to load Kestrel configuration from the loaded config
  • Adds Routing
  • Adds IIS Integration

That sounds like a lot, but if we again go back to what we used to write :

It’s just now doing all of this under the hood for us (and more!). Nice!

.NET Core 3.0 Preview 7 has been released as of July 23rd. You can grab it here : https://dotnet.microsoft.com/download/dotnet-core/3.0

What’s Included

The official post from Microsoft is here : https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0-preview-7/ but you’re not going to find anything shiny and new to play with. Infact the post explicitly states “The .NET Core 3.0 release is coming close to completion, and the team is solely focused on stability and reliability now that we’re no longer building new features“. So if something hasn’t made it into .NET Core 3.0 by now, you might be waiting until 3.1.

But that doesn’t mean we can’t take a look at what’s been happening under the hood. So I took a look at the Github issue list to see what did make it to this release, even if it wasn’t worth a shout out in the official blog post. In particular, there seems to be two main areas that has garnered quite a few taggings.

JsonSerializer Bugs

Unsurprisingly with .NET Core moving away from JSON.NET and instead moving to use their own JSON Serializer, there has been bugs a plenty. At a glance, it mostly looks like edgecase stuff where in particular scenarios, serializing and deserializing is not working as expected. Things like JSON Should be able to handle scientific notation.

Blazor Bugs

Blazor has been getting a major push recently – I’m seeing it show up more and more in my twitter feed. And along with people using it for realworld work loads, comes people logging bugs. To be brutally honest, I haven’t used Blazor at all. It feels like it’s trying to solve a problem that doesn’t exist somewhat like the early days of ASP.NET WebForms. (And feel free to drop a comment below about how I’m totally wrong on that!).

Worth Updating?

One thing worth mentioning is that Microsoft say “NET Core 3.0 Preview 7 is supported by Microsoft and can be used in production“. So they obviously feel confident enough that this is a proper Release Candidate. But in terms of getting this because there is something new in there that you definitely need to get a hold of, it’s probably worth skipping for now.