The past few days I’ve been setting up a SonarQube server to do some static analysis of code. For the most part, I was looking for SonarQube to tell us if we had some serious vulnerabilities lurking anywhere deep in our codebases, especially some of the legacy code that was written 10+ years ago. While this sort of static analysis is pretty limited, it can pick up things like SQL Injection, XSS, and various poor security configuration choices that developers sometimes make in the heat of the moment.

And how did we do? Well.. Actually pretty good! We don’t write raw SQL queries, instead preferring to use EntityFramework Linq2SQL, which for the most part protects us from SQL injection. And most of our authentication/authorization mechanisms are out of the box .NET/.NET Core components, so if we have issues there… Then the entire .NET ecosystem has bigger problems.

What we did find though was millions of non-critical warnings such as this :

Unused "using" should be removed

I’ll be the first to admit, I’m probably more lenient than most when it comes to warnings such as this. It doesn’t make any difference to the code, and you rarely notice it anyway. Although I have worked with other developers who *always* pull things like this up in code reviews, so each to their own!

My problem was, SonarQube is right, I probably should remove these. But I really didn’t want to manually go and open each file and remove the unused using statements. I started searching around and low and behold, Visual Studio has a feature inbuilt to do exactly this!

If you right click a solution or project in Visual Studio, you should see an option to “Analyze and Code Cleanup” like so :

I recommend first selecting “Configure Code Cleanup” from this sub menu so that we can configure exactly what we want to clean up :

As you can see from the above screenshot, for me I turned off everything except removing unnecessary usings and sorting them. You can of course go through the other available fixers and add them to your clean up Profile before hitting OK.

Right clicking your Solution/Project, and selecting “Analyze and Code Cleanup” then “Run Code Analysis” will instantly run these fixers over your entire project or solution. Instantly letting you pass this pesky rule, and cleaning up your code at the same time!

Now I know, this isn’t exactly a big deal removing unused usings. I think for me, it was more the fact I didn’t even know this tool existed right there in vanilla Visual Studio.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Ever since I started using constructor dependency injection in my .NET/.NET Core projects, there has been essentially a three step process to adding a new dependency into a class.

  1. Create a private readonly field in my class, with an underscore prefix on the variable name
  2. Edit the constructor of my class to accept the same type, but name the parameter without a prefix
  3. Set the private readonly field to be the passed in parameter in the constructor

In the end, we want something that looks like this :

public class UserService
{
    private readonly IUserRepository _userRepository;

    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }
}

Well at least, this used to be the process. For a few years now, I’ve been using a nice little “power user” trick in Visual Studio to do the majority of this work for me. It looks a bit like this :

The feature of auto creating variables passed into a constructor is actually turned on by default in Visual Studio, however the private readonly with an underscore naming convention is not (Which is slightly annoying because that convention is now in Microsoft’s own standards for C# code!).

To add this, we need do the following in Visual Studio. The exact path to the setting is :

Tools => Options => Text Editor => C# => Code Style => Naming

That should land you on this screen :

The first thing we need to do is click the “Manage naming styles” button, then click the little cross to add. We should fill it out like so :

I would add that in our example, we are doing a camelCase field with an underscore prefix, but if you have your own naming conventions you use, you can also do it here. So if you don’t use the underscore prefix, or you use kebab casing (ew!) or snake casing (double ew!), you can actually set it up here too!

Then on the naming screen, add a specification for Private or Internal, using your _fieldName style. Move this all the way to the top :

And we are done!

Now, simply add parameters to the constructor and move your mouse to the left of the code window to pop the Quick Actions option, and use the “Create and Assign Field” option.

Again, you can actually do this for lots of other types of fields, properties, events etc. And you can customize all of the naming conventions to work how you like.

I can’t tell you how many times I’ve been sharing my screen while writing code, and people have gone “What was that?! How did you do that?!”, and by the same token, how many times I’ve been watching someone else code and felt how tedious it is to slowly add variables one by one and wire them up!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

In the coming months I’ll be covering the new features of .NET 6, including things like MAUI (Cross platform GUI in .NET), PriorityQueue, and so much more. So I thought it would be worth talking a little bit on how to actually get set up to use .NET 6 if you are looking to touch this new tech early on.

In previous versions of .NET/.NET Core, the process to accessing preview versions was somewhat convoluted and involved installing a second “preview” version of Visual Studio to get up and running, but all that’s out the window now and things are easier than ever!

Setting Up .NET 6 SDK

To start, head over to the .NET 6 download page and download the latest SDK (not runtime!) for your operating system : https://dotnet.microsoft.com/download/dotnet/6.0

After installing, from a command prompt, you should be able to run “dotnet –info” and see something similar to the below :

.NET SDK (reflecting any global.json):
 Version:   6.0.100-preview.2.21155.3
 Commit:    1a9103db2d

It is important to note that this is essentially telling you that the default version of the .NET SDK is .NET 6 (Although, sometimes in Visual Studio, it will ignore preview versions as we will shortly see). This is important to note because any projects that don’t utilize a global.json will now be using .NET 6 (and a preview version at that). We have a short guide on how global.json can determine which SDK is used right here.

Setting Up Visual Studio For .NET 6

Now for the most part, developers of .NET will use Visual Studio. And the number one issue I find when people say “the latest version of .NET does not work in Visual Studio”, is because they haven’t downloaded the latest updates. I don’t care if a guide says “You only need version X.Y.Z” and you already have that. Obviously you need Visual Studio 2019, but no matter what anyone tells you about required versions, just be on the latest version.

You can check this by going to Help, then Check For Updates inside Visual Studio. The very latest version at the time of writing is 16.9.1, but again, download whatever version is available to you until it tells you you are up to date.

After installing the latest update, there is still one more feature flag to check. Go Tools -> Options, then select Preview Features as per the screenshot below. Make sure to tick the “Use previews of the .NET Core SDK”. Without this, Visual Studio will use the latest version of the .NET SDK installed, that is *not* a preview version. Obviously once .NET 6 is out of preview, you won’t need to do this, but if you are trying to play with the latest and greatest you will need this feature ticked.

After setting this, make sure to restart Visual Studio manually as it does not automatically do it for you. And you don’t want to be on the receiving end of your tech lead asking if you have “turned it off and on again” do you!

Migrating A Project To .NET 6

For the most part, Visual Studio will likely not create projects in .NET 6 by default when creating simple applications like console applications. This seems to vary but.. It certainly doesn’t for me. But that’s fine, all we have to do is edit our csproj file and change our target framework to net6.0 like so :

<TargetFramework>net6.0</TargetFramework>

If you build and you get the following :

The current .NET SDK does not support targeting .NET 6.0.  Either target .NET 5.0 or lower, or use a version of the .NET SDK that supports .NET 6.0

The first thing to check is

  1. Do you have the correct .NET 6 SDK installed. If not, install it.
  2. Is .NET 6 still in preview? Then make sure you have the latest version of Visual Studio *and* have the “Use previews of the .NET Core SDK” option ticked as per above.

And that’s it! You’re now all set up to use the juicy goodness of .NET 6, and all those early access features in preview versions you’ve been waiting for!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Free C# 9 Video Course

Are you one of those people that sees a big wall of text on a programming blog and instantly tunes out? Well you aren’t alone! In fact, I got hassled so much with people asking me “Can’t you just quickly share your screen and show me?” rather than reading a blog post, I decided I may as well quickly record the need to know bits of C# 9. So that’s what I’ve done!

My “What’s New In C# 9” course is completely free and will get you up and using C# 9 features in less than an hour (seriously!). Did I mention it’s FREE?

Watch For Free Now!

As .NET 5 is rolled out, so too is another version of C#, this time being C# 9. I’m actually pretty excited for some of the features that, fingers crossed, should make it into the final release. But as always, I don’t want to wait till the official release, and instead jump in early and play with all the new shiny things.

So in actual fact, getting setup with C# 9 is basically the same as getting setup with .NET Preview 5. And luckily for you, we have a shiny guide right here : https://dotnetcoretutorials.com/2020/05/22/getting-started-with-net-5-and-the-msbuild-net-5-cliffnotes/. But for the cliffnotes of that post :

  • Download and install the latest .NET 5 SDK from here : https://dotnet.microsoft.com/download/dotnet/5.0
  • Ensure that your version of Visual Studio 2019 is atleast 16.7 by clicking Help => Check For Updates inside Visual Studio. If in doubt, update.
  • Go Tools => Options inside Visual Studio, then select “Preview Features” and tick the box that says “Use previews of the .NET Core SDK”. Then restart Visual Studio.

Once the .NET 5 Preview SDK is installed and setup, then the only thing you need to do is edit your .csproj file and add a lang element like so :

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <LangVersion>9.0</LangVersion>
  </PropertyGroup>
</Project>

Troubleshooting

If you’ve done all of that and you get either of these errors :

The reference assemblies for .NETFramework,Version=v5.0 were not found. 

Or

Invalid option '9.0' for /langversion. Use '/langversion:?' to list supported values.

Then here’s your quick and easy troubleshooting list :

  • Are you sure you’ve got the latest .NET 5 SDK installed? Remember it’s the SDK, not the runtime, and it’s .NET 5.
  • Are you sure you’re Visual Studio is up to date? Even if you have the SDK installed, Visual Studio plays by it’s own rules and needs to be updated.
  • Are you using Visual Studio 2019? Any version lower will not work.
  • Are you sure you enabled Preview SDKs? Remember Tools => Options, then “Preview Feature”

Keeping Up To Date

A new preview version of .NET 5/C#9 comes out every few months. So if you’re reading about a new C# 9 or .NET 5 feature that someone is using but you can’t seem to get it to work, then always head back to https://dotnet.microsoft.com/download/dotnet/5.0 and download the latest preview version and install. Similar for Visual Studio, while typically less of an issue, try and keep it up to date as so often latest features not working are simply that I’m on a version that was perfectly fine a month ago, but is now out of date.

C# 9 Features

We are slowly working our way through all new C# 9 features, if you are interested in other new additions to the language, check out some of the posts below.

All of these will be covered in detail coming soon!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

NOTE : This post was initially written in early 2017 (!!!) but has now been completely revamped in 2020 to be up to date with .NET Core 3+ Watch feature. The original article was written in pre 1.0 days and is no longer relevant. But this is still a killer feature and should be used far more often!

One of the most overlooked features of .NET Core CLI is the “dotnet watch” command. With it, it allows you to have a “live reload” of your ASP.NET Core site running without having to either run the “dotnet run” command, or worse do the “Stop the process in Visual Studio. Write your changes. Recompile and run again” routine. The latter can be very annoying when all you are trying to do is do a simple one line fix.

If you are used to watches in other languages/tooling (Especially task runners like Gulp), then you will know how much of a boost watches are to productivity.

The Basics

I highly recommend creating a simple ASP.NET Core project to run through this tutorial with. The tooling can be a little finicky with large projects so it’s easier to get up and running with something small, then take what you’ve learned onto something a little larger.

For this demo, I have a simple controller that has a get method that returns a string value.

[Route("api/home")]
public class HomeController : Controller
{
	[HttpGet]
	public string Get()
	{
		return "Old Value";
	} 
}

Open a command prompt in your project directory, a terminal in VS Code, or even the Package Manager Console in Visual Studio and run the following command :

dotnet watch run

Note that if you previously have had to run the “dotnet run” command with other flags (e.g. “dotnet run -f net451” to specify the framework), this will still work using the watch command. Essentially it’s saying “Do a watch, and when something changes, do ‘this’ thing” which in our case is the run command.  You should see something similar to the following :

dotnet watch run
watch : Started
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development

This means you are up and running. If I go to http://localhost:5000/api/home, I should see my controller return “Old Value”.

Now I head back to my controller and I change the Get action to instead return “New Value”. As soon as I hit save on this file I see the following in my console window :

watch : Exited
watch : File changed: C:\Projects\WatchExample\Controllers\HomeController.cs
watch : Started
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000

What we see is that the watch immediately exits, and it tells us that a file has been changed in HomeController.cs and so it starts recompiling immediately. When we browse to http://localhost:5000/api/home we see our “New Value” shown and we didn’t have to do anything else in terms of manually recompiling or running a new dotnet run command.

On larger projects, the recompile process can actually be a little slow so it’s not always an instant “change code and immediately refresh the browser” moment. Especially if you have a large dependency tree that means several projects need to be rebuilt before the site is back up and running. But it’s still going to be faster than whatever manual process you are used to.

Debugging With dotnet watch

So previously, debugging while using dotnet watch was almost a fruitless exercise. Each time your watch started and ran, a new “dotnet.exe” process would spin up. But the issue was it was impossible to find the “right” process to attach your debugger to. You might have a half dozen or so dotnet.exe processes running and you sort of had to wing it and pick the one that had been created most recent and hope for the best. Then each time you made a change, a *new* dotnet.exe would be spun up and your attached debugger was useless with you having to start the attach to debugger process all over again. Ugh!

As of .NET Core 3+, this is now much much easier.

Suppose I have my project up and running on a watch. In Visual Studio I simply go  Debug -> Attach To Debugger. I then filter all processes by the actual name of my project. In my case I called my project “WatchExample”, so I just start typing that into the filter box.

I click the Attach button and I’m away! Unfortunately each time you make a change the debugger is stopped while your project recompiles, but a helpful hint is to learn the “Reattach To Process” hotkey which in default Visual Studio key bindings is “Shift + Alt + P”. This immediately attaches the debugger to the last process it was on (Which in our case, is the our project exe), and we are away debugging again!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

I’ve recently had the opportunity to start a Specflow/Selenium end to end testing project from scratch and my gosh it’s been fun. I’m one of those people that absolutely love unit tests and trying to “trick” the code with complicated scenarios. End to end testing with Selenium is like that but on steroids. Seeing the browser flash infront of you and motor through tests is an amazing feeling.

But in saying that. A key part of using Selenium is the “ChromeWebDriver”. It’s the tool that actually allows you to manipulate the Google Chrome browser through selenium. And let me tell you, there are a few headaches getting this set up that I really didn’t expect. Version errors, Not finding the right exe, Nuget packages that actually include the exe but it’s the wrong version or can’t be found. Ugh.

If you are not that big into automation testing, you can probably skip this whole post. But if you use Specflow/Selenium even semi-regularly, I highly recommend bookmarking this post because I’m 99% sure you will hit atleast one of these bugs when setting up a new testing project.

Chrome, Gecko  and IE Drivers

While the below is mostly about using ChromeDriver, some of this is also applicable for Gecko (Firefox), and IE drivers. Obviously the error messages will be slightly different, but it’s also highly likely you will run into very similar issues.

Adding ChromeDriver.exe To Your Project

The first thing to note is that you’ve probably added the “Selenium.WebDriver” and maybe “Specflow” nuget packages. These however *do not* contain the actual ChromeDriver executable. They only contain the C# code required to interact with the driver, but *not* the driver itself. It is incredibly confusing at first but kinda makes sense because you may want to only use Chrome or only Firefox or a combination etc. So it’s left up to you to actually add the required driver EXEs.

If you try and run your selenium tests without it, it will actually compile all fine and look like starting only to bomb out with :

The chromedriver.exe file does not exist in the current directory or in a directory on the PATH environment variable.

Depending on your setup, it can also bomb out with :

The file C:\path\to\my\project\chromedriver.exe does not exist. 
The driver can be downloaded at http://chromedriver.storage.googleapis.com/index.html

So there are two ways to add ChromeDriver to your project. The first is that you can install a nuget package that will write it to your bin folder when building. The most common nuget package that does this is here : https://www.nuget.org/packages/Selenium.WebDriver.ChromeDriver/

But a quick note, as we will see below, this only works if everywhere you run the tests has the correct version of chrome that matches the driver. What?! You didn’t know that? That’s right. The version of ChromeDriver.exe will have a version like 79.0.1.1 that will typically only be able to run on machines that have chrome version 79 installed. The nuget package itself is typically marked with the version of Chrome you need, so it’s easy to figure out, but can still be a big pain in the butt to get going.

So with that in mind, the other option is to actually download the driver yourself from the chromium downloads page : https://chromedriver.chromium.org/downloads

You need to then drop the exe into your project. And make sure it’s set to copy if newer for your build. Then when building, it should show up in your bin folder. Personally, I found the manual download of the chromium driver to be handy when working in an enterprise environment where the version of chrome might be locked down by some group policy, or you are working with others who may have wildly different versions of chrome and you can do funky things like have different versions for different developers.

Passing The ChromeDriver Location

So you’ve downloaded ChromeDriver and when you build, you can see it in your bin folder, but everything is still blowing up with the same error, what gives?!

One of the more irritating things I found is that in so many tutorials, they new’d up a chromedriver instance like so :

ChromeDriver = new ChromeDriver();

Now this may have worked in .NET Framework (I haven’t tried), but atleast for me in .NET Core, this never works. I think there must be something inside the constructor of ChromeDriver that looks up where it’s current executable is running (e.g. where the Bin folder is), and in .NET Core this must be different from Full Framework.

In anycase, you can change the constructor to instead take the folder location where it can find the driver. In my case I want that to be the bin folder :

ChromeDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

Obviously you can go ahead and change the path to anything which is super handy for differing dev setups. For example you could ask each dev to maintain their own version of chromedriver.exe somewhere on their C:\ drive, and then just pass that location into the constructor. Meaning that each developer can have a completely different version of chrome, and things will still run perfectly fine.

Versions Matter

We kinda touched on it above, but versions of ChromeDriver have to match the actual version of Chrome on the machine. If you are getting errors like so :

session not created: This version of ChromeDriver only supports Chrome version XX

Then you have a mismatch between versions.

The easiest way to rectify the issue is to manually download the correct version of ChromeDriver from here : https://chromedriver.chromium.org/downloads and force your code to use it. If you are using a nuget package for the driver, then it’s highly likely you would need to switch away from it to a manual setup to give you better control over versioning.

Azure Devops (And Others) Have ChromeDriver Environment Variables

This is one that I really wish I knew about sooner. When I tried to run my Selenium tests on Azure Devops, I was getting version issues where the version of Chrome on my hosted build agent was just slightly different from the one on my machine. I tried to do all sorts of crazy things by swapping our the exe version etc, but then I found buried in a help doc that there is actually an environment variable named ChromeWebDriver that has the full path to a chromedriver that is guaranteed to match that of the chrome browser on the agent. So I wrote some quick code that if I was running inside Azure Devops, to grab that environment variable and pass that into my ChromeDriver constructor.

Again, this is only for Azure Devops. But if you are using Gitlab, Bamboo, TeamCity, whatever! Check to see if there is an environment variable on hosted agents that carries the location of ChromeDriver.

If you are using your own build agents, then it’s also a good idea to think about following the same pattern. It’s super handy to have the Build Agent look after it’s own versions rather than wrangling something in code to fudge it all.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

In a previous post we looked at how we can publish a single exe from a .NET Core project. Now in it, I talk about how the resulting binary is absolutely massive, 70MB for a simple hello world console app! But I also talked about how there are now ways to significantly chop that down.

Despite that, when shared with Reddit, there was some comments that weren’t so impressed. Most notably this gem :

But that’s cool. For Scellow and anyone else that wasn’t impressed with the size of the exe, let’s look at how we can chop it down.

You Need .NET Core 3.0 (Preview 6+)

Like all these features I’m writing about recently, you’re gonna need the very latest version of .NET Core 3.0. At the time of writing it’s Preview 6. Any version earlier will simply not fly. And again, if that isn’t you and you don’t want to muck around with preview versions, then you’ll just have to wait!

PublishedTrimmed Flag

Before we go on, you might hear IL Linker talked about a lot. Possibly because it’s in the title of this post! But that’s because IL Linker is essentially the backbone of this entire feature. However where previous it was this external tool you had to grab from a nuget feed, now it’s built directly into .NET Core 3.0+ which is pretty impressive!

Anyway we previously published our application using the following command :

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true

And with that, we ended up with an exe over 70MB big :

Not good. But literally all we have to do is add one flag and we can chop it down a bit :

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true

So… 29MB. And this is about the time where you go “but shouldn’t this be KB in size?”. And honestly the answer is yes. It should be. But we have to remember that this is still a completely self contained application that doesn’t even require the target machine to know what .NET Core is. So even if we aren’t using things like say.. cryptography so we can get rid of that, there is probably a lot of basic and primitive .NET Core features that we just can’t get rid of.

Still. It’s an exe half the size with no functional difference between the two.

Reflected Assemblies

Through various forms of reflection, we may end up loading assemblies at runtime that aren’t direct references. Take this (very convoluted) example of loading an assembly at runtime :

static void Main(string[] args)
{
    Console.WriteLine(Assembly.Load("System.Security").FullName);
    Console.ReadLine();
}

Now when debugging this locally, and we have .NET Core installed, we ask for System.Security and it knows what that is because we are using the installed .NET Core platform. So running it, we get :

System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

But if we publish this using the PublishTrimmed flag from the command line, then run it :

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Security, Culture=neutral, PublicKeyToken=null'. 
The system cannot find the file specified.

Unsurprisingly, we have trimmed a bit too much off. Because I don’t actually reference System.Security anywhere, it’s decided we aren’t actually using it. But there is a way to specify that we know best, and to package it up for us.

All we need to do is edit our csproj file for our project and add :

<ItemGroup>
  <TrimmerRootAssembly Include="System.Security" />
</ItemGroup>

Now we will bundle up System.Security with our single exe and everything will run smooth! Pretty nice I have to say!

You may ask yourself “Well how will I know when I need to do this?”. Frankly 99% of the time you won’t. If you decide to trim your exe, you will need to really give it a good test before letting it out into the wild.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Say I have a simple “Hello World” console application that I want to send to a friend to run. The friend doesn’t have .NET Core installed so I know I need to build a self contained application for him. Easy, I just run the following command in my project directory :

dotnet publish -r win-x64 -c Release --self-contained

Pretty self explanatory :

  • Publish the project from the current directory
  • Build the project to run on Windows 64 bit machines
  • Build in release configuration mode
  • Publish everything as “self-contained” so that everything required to run the app is packaged up with our executable

So this works right, we end up with a folder that has our exe and everything that is required to run it, but the issue is that there is a tonne required to run even a HelloWorld console app.

All up it’s a little over 200 files. Crazy – but it makes sense. It’s essentially having to package the .NET Core runtime just to run Hello World.

So functionally, this works. But optics wise, it looks like a mess. I’ve sent folders like this to clients and had to say “uhh.. So I’m going to send you a folder with hundreds of files in it… But… Can you just find the one titled MyApplication.exe and run that and don’t worry about the rest?”. When people are used to having an icon on their desktop they double click and things just.. work… This just doesn’t cut it.

You Need .NET Core 3.0 (Preview 5+)

I need to put that in bold because this will not work if you don’t have .NET Core 3.0. And if you are an early adopter (At the time of this post .NET Core 3.0 is not GA yet), you will need atleast preview 5 upwards. If you’re not one to mess around in preview’s, then you can just wait a few months till .NET Core 3.0 is released!

The PublishSingleFile Flag

All that intro and it literally comes down to a single command flag :

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true

All this does is runs our publish command but tells it to package it within a single file. You’ll notice that we no longer specify the self-contained flag. That’s because it’s assumed that if you are packaging as a single exe, that you will want all it’s dependencies along with it. Makes sense.

And the output :

A single tidy exe! When this is executed, the dependencies are extracted to a temporary directory and then everything is ran from there. It’s essentially a zip of our previous publish folder! I’ve had a few plays around with it and honestly, it just works. There is nothing more to say about it. It just works.

Helpful Tip : Make sure you clean your publish directory or just outright delete your bin folder. It doesn’t break anything to not do so, but all those old DLL’s just hang around until you do so your nice single EXE is hard to spot. 

File Size And Startup Cost

Keen eyes will notice something about the above screenshot. The file size. It’s over 70MB! That’s crazy for an application that does nothing but print Hello World to the screen! This is solved in Preview 6 of .NET Core 3.0 with a feature called IL Linker or Publish trimmer that omits DLL’s that aren’t used. You can read more about that here!

The other issue you may find is that there is a slight startup cost when running the self contained executable for the first time. Because it needs to essentially unzip all dependencies to a temporary directory on first run, that’s going to take a little bit of time to complete. It’s not crazy (5 seconds or so), but it’s noticeable. Luckily on subsequent runs it uses this already unzipped temp folder and so startup is immediate.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

I’ve previously done posts on how to setup both .NET Core 2.1 and .NET Core 2.2. The reason for these posts was because it was still a little shaky exactly which version of the SDK you needed to actually build for these platforms. e.x. If you had .NET Core SDK 2.1, it didn’t actually mean you could build .NET Core 2.1 projects (How infuriating is that?!).

But things have gotten better and now it’s usually just a matter of installing the latest SDK and away you go, so there isn’t really much I could normally write for each version bump. However! .NET Core 3 includes a couple of really important updates that I want to talk about in the future. Windows Forms/WPF development on top of .NET Core, and C# 8. Because of this, I wanted to have a post all written up on setting up your machine for .NET Core 3 development while things are in preview so I don’t have to repeat myself every future post!

Installing the .NET Core 3 Preview SDK

Installing the .NET Core 3 SDK is fairly straight forward. Just head to the download page and grab the SDK (Not the runtime) and install! You do want to ensure you are on the .NET Core 3 page and not the general download page of .NET Core as the current “live” version is 2.2 not 3.

Once installed, you should be able to open a command prompt and run dotnet –info with the output being something close to :

.NET Core SDK (reflecting any global.json):
 Version:   3.0.100-preview-009812
 Commit:    e3abf6e935

Of course as long as the version is 3+, you should be good to go.

It’s also important to note that your default SDK on your machine will now be 3 and not 2.2 (Or the previous version you had installed). If you have existing projects that are using this SDK version, you will need to create a new global.json file to be able to run different SDK’s side by side. Luckily there is a great guide on how to do this right here!

Using VS Code

If you like programming in VS Code, then you’re actually good to write .NET Core 3 code right from the get go (Since it’s just a text editor). Obviously you will want to install the “C#” extension if you want all the good intellisense (Including for C# 8 new types), but other than that because builds are all from the command line there isn’t too much to it.

If you want to use C# 8 features in VS Code, see that section of this article below (It’s the same for Visual Studio or VS Code).

Using Visual Studio

A preview version of .NET Core also has a preview version of Visual Studio to accompany it. This can be a little annoying because it’s not just jumping on the “preview” update track for your existing Visual Studio installation, you actually need to download and install a completely new version of Visual Studio. This means another ~6GB of space taken up with a VS version you may use once or twice to try out new features.

I feel the need to point this out because it caught me out initially. The first version of Visual Studio to support .NET Core 3.0 is Visual Studio 2019 Preview 1. Emphasise on the 2019 part because I was wondering why my 2017 preview Visual Studio wasn’t working at first!

You can grab the preview version of Visual Studio here : https://visualstudio.microsoft.com/vs/preview/

I have actually dabbled with a solo installation of the preview version only and not bothered with the current release version. Theoretically it could have a few more bugs in it than the current supported release, but so far so good!

Enabling C# 8 Features

We can enable C# 8 on a project by project basis by editing our .csproj files. Simply open up your project file, and add the following anywhere within your <Project> node :

<PropertyGroup>
	<LangVersion>8.0</LangVersion>
</PropertyGroup>

And that’s literally it (Too easy!).

Some people get trapped thinking that the following will enable C# 8 features :

<PropertyGroup>
	<LangVersion>latest</LangVersion>
</PropertyGroup>

But remember, version 8 of the language is in preview too. Latest refers to the latest minor version that has actually been released (So at this time, 7.3). If you try and use new features of C# 8, for example the “Range” type, you will get an error like so :

error CS8370: Feature ‘range operator’ is not available in C# 7.3. Please use language version 8.0 or greater.

But other than that, everything is pretty straight forward! Now go ahead and start using Range, AsyncEnumerable, Indices and Nullable Reference Types!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Recently while upgrading a couple of projects to .NET Core 2.2, I came across this error.

This version of Microsoft.AspNetCore.App is only compatible with the netcoreapp2.1 target framework. 
Please target netcoreapp2.1 or choose a version of Microsoft.AspNetCore.App compatible with netcoreapp2.2.

A quick google revealed that actually people had the same issue when their projects were going from 2.0 to 2.1 too. And all the fixes seemed kinda flaky and typically involved “Try this and pray” type steps.

To be honest, I know how to fix diagnose and fix the issue, but I don’t really know why that particular error message is the one that comes up.

First thing I noticed is that this error will only ever happen when you’ve tried opening a project in Visual Studio and tried to build. In some cases I’ve been able to build using the dotnet CLI, but not inside Visual Studio. If after building in Visual Studio, I then try and build from the dotnet CLI tool, I then start getting this error too. However if I delete the bin folder and rebuild from the CLI, we are all clear.

Next, in all cases the version of .NET Core I want to target is not available and not selected for my project inside VS. So if I right click my project and view properties, the Target Framework is blank :

This is because the version of Visual Studio that I’m using doesn’t actually support the version of .NET Core I am trying to run. It’s sort of this weird situation where even if you have the correct .NET Core SDK installed, that really only sets you up for using the dotnet CLI and writing code in something like VSCode.

All you need to do is update Visual Studio. Let me put that in big bold letters so people coming from Google can get their answer fast :

You Need To Update Visual Studio

Hopefully that’s clear enough!

Even once you update Visual Studio, you will likely need to delete the bin and obj folders of your project and then rebuild again from VS. Now there may be one very edge case that this doesn’t resolve your issues. And that’s if you are using the very latest preview builds for .NET Core SDK that Visual Studio either doesn’t support yet, or only supports in the Pre-Release version of VS. Rare, but it does happen.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.