Today’s header image was created by Marcos Luiz Photograph at Unsplash
Cast your mind back to part one of this series
it wasn’t that long ago
and you’ll remember that I said that I was going to provide some answers to the some of the most common questions on Stack Overflow, ones which fell into one of the following (very loose) categories:
- “How do I use a .NET Core library with .NET Framework?” (and vice versa)
- “Why can’t I use this Windows specific API call on Linux via .NET Core?”
- “I want to target some old NuGet package on both a .NET Core and a .NET Framework project. My Framework project is running either 3.5 or 4.1, why can’t I use the same NuGet package?”
- “I haven’t read any of the documentation or done any searching, but why can’t I do x in .NET Core?”
- “I didn’t search to see whether anyone else has had the same issue, so I’ll just post mine and hope for the best”
I’ve had a little time to think, and to gather some links to actual questions on Stack Overflow (so that I can show real examples of these loosely defined categories) since putting out the first part. My goal here is not to name-and-shame, but I feel like it will be a side effect of this blog post’s main goal: to highlight what a set of bad questions looks like.
I’ll split this post into sections, each section will have the question category as the header. Within each section have links to examples of questions which fall into this category, I’ll also include a basic answer.
“How do I use a .NET Core library with .NET Framework?” (and vice versa)
Here are some examples of this question category:
- Reference a .Net 4.6.2 project in a .NetCore project (VS2017 15.4.4)
- .Net Core and Full Framework projects in one solution
- Problems in compatibility of .NET Core with .Net Framework below of 4.7.1
- Referencing .net full framework package from .net core 2
These questions all revolve around calling .NET Framework APIs and libraries using .NET Core
One unifying point across all of these questions (and ones which are very similar to them) is what seems like a lack of exposure to .NET Standard. I’ve written about .NET Standard before, the problem that it addresses, and what it allows us to do with .NET Core applications and .NET Framework libraries.
I realise that I’m a small fish in a very, very big pond, but it’s not like Microsoft haven’t been vocal about .NET Standard. There’s the above linked GitHub repo for the Standard, there are a series of blog posts (started back in September of 2016) which talked about the Standard, Microsoft have produced a large number of videos about .NET Standard, and there’s also the series of YouTube videos that Immo Landwerth put out about the Standard (which I’ll embed below).
So it’s not like it’s been kept secret.
Granted, the name isn’t brilliant. In fact, this is one of the things which was brought up during my most recent interview on the Cynical Developer.
My stock answer to these question is something along the lines of:
you’ll notice that these links are the same as those from the above section
The tl;dr is that .NET Standard lists the APIs and methods which you can expect a .NET application which runs on one of the platforms in the ecosystem (i.e. Framework, Core, WPF, Xamarin, etc.) to have access to. Higher version numbers of the standard include more APIs but reduce the number of platforms within the ecosystem that you can use.
Here’s a visual of how .NET Standard is adopted and supported by the different frameworks:
Along the top of the table are the versions of .NET Standard, and down the left side are the versions of the platforms which implement the standard. Using this chart, you can see that .NET Standard 2.0 is supported by:
- .NET Core 2.0
- .NET Framework 4.6.1
- Mono 5.4 etc.
This means that any application which targets any of those frameworks will have access to the APIs listed in .NET Standard 2.0
A C# example using interfaces and classes would be the following:
|interface INetStandardV1_3 : INetStandardV1_1|
|interface INetStandardV2_0 : INetStandardV1_3|
|class NetFrameworkV4_5 : INetStandardV1_1|
|class NetCoreV1_1 : INetStandard V1_1|
|class NetFrameworkV4_6 : INetStandardV1_3|
|class NetCoreV1_3 : INetStandardV1_3|
|class NetFrameworkV4_6_1 : INetStandardV2_0|
|class NetCoreV2_0 : INetStandardV2_0|
This works fantastically because the .NET Standard is, at it’s root, a set of interfaces which the different versions of .NET Framework and .NET Core
along with any other platform in the .NET Ecosystem
For a much more in depth description of the .NET Standard, it’s worth watching this video on Channel 9 with Immo Landwerth and Rich Lander.
“I haven’t read any of the documentation or done any searching, but how do I do x in .NET Core?”
Here are some examples of questions in this category:
it seems a little unfair to pick this one, though
- ASP.NET Core Authorization Based On Query String
- How to create a new dotnet core application that has both auth and EF?
These kinds of questions are all based around assumptions made about .NET Core or ASP.NET Core. These assumptions are usually based on the developer experience with .NET Framework or ASP.NET, whereas the developer experience for Core is slightly different in some places. A lot of this can be solved by reading the documentation for either .NET Core or ASP.NET Core.
The engineering team at Microsoft have open sourced all of their documentation
like, for almost everything that Microsoft do
and are hosting it over at docs.microsoft.com. Since it’s open source, a lot of people in the community have been adding stuff or making edits to the entire documentation tree. This means that there has been an explosion of really good documentation for both .NET Core and ASP.NET Core.
And .NET Framework, too
I guess the only excuse for not heading over there and searching is that folks don’t know about it. To be fair, Microsoft haven’t been as loud at promoting their new documentation as they could have been.
“I want to target some old NuGet package on both a .NET Core and a .NET Framework project. My Framework project is running very 3.5 or 4.1, why can’t I use the same NuGet package?”
Here is an example of questions in this category:
The issue with this questions is somewhere in between “not reading the documentation” and “not searching”.
The thing about .NET Core is that there are APIs in the full Framework which couldn’t be ported to Unix-like OSs (Mac OS and Linux distributions):
- Because they’re fundamentally baked into Windows or
- They couldn’t be ported across in time for the release schedule.
The second reason implies that these APIs will eventually be added into .NET Core, but not yet. What you have to remember is that .NET Framework has had over 16 years to mature by this point, and that APIs which we now take for granted (LINQ and Async for example) weren’t included until very late in the game (2007 and 2012, respectively).
This doesn’t mean that we’ll be waiting for a decade for these APIs, but it does mean that we might have to wait some time. What’s great about the .NET Core release cycles is that everything
well, almost everything
is out in the open. If you want a feature, head over the GitHub repo and ask for it. Be aware though, that there is a specific format required for logging issues and making requests.
But what if you don’t know whether some API is available, I hear you ask. Well, that’s where apisof.net comes in. Imagine it as a search engine for the .NET Standard, with the ability to tell you which platforms (and which versions) in the ecosystem have support for your chosen API.
Here’s the data that it has on
System.Xml.XmlElement, for example:
Not only does this tell you which platforms are supported, but which versions too.
“Why can’t I use this Windows specific API call on Linux via .NET Core?”
Here are some examples of questions in this category:
- How to reference System.Windows.Forms from a net462 targeting SDK project
- Using .NET Core to create windows applications
These questions are extensions of the previous types combined together.
The answer lies somewhere in an extension to the previous category (“I haven’t read any of the documentation or done any searching, but how do I do x in .NET Core?”), in that .NET Core is both a subset of .NET Framework and is cross platform.
We have two separate points here. First, that it is, effectively, a subset of .NET Framework. There are some things which .NET Framework can do which .NET Core can’t
again, see the previous question category
Consider the following (extremely badly put together Venn diagram):
The green section represents the .NET Framework API space and the orange section represents the .NET Core API space.
this isn’t accurate for a bunch of reasons, but it’ll do for now
The .NET Framework API space is larger and encompasses stuff that the .NET Core API space doesn’t, but the .NET Core API space has some of the stuff that the .NET Framework has.
That’s point number one.
Point number two is that, by its very nature, .NET Core is cross platform. This means that it has to support a lot of operating system level stuff that .NET Framework never had to support. And not just things like using ‘/’ instead of ‘\’ in file paths, either.
All of the system calls on Linux and Unix-like OSs are different to those on Windows
I shan’t go into why, they just are
and a lot of the logical separation of stuff is just different; timing is different; interrupts are different; everything is different. As such, the engineers who have been working on .NET Core
and by extension ASP.NET Core
have been working really hard to ensure that we get access to the APIs that we know and use.
It’s meant that some APIs have had to take a back seat, whilst others are being worked on.
And that doesn’t even cover the stuff which is too heavily baked into Windows to port over – things like System.WindowsRuntimeExtensions, System.Windows.Forms, and (pretty much) anything in the System.Windows namespaces. These APIs will, likely, never be included in .NET Standard or ported to .NET Core.
But that doesn’t mean you shouldn’t use .NET Core, after all the goal (at least for the time being) isn’t to replace .NET Framework with .NET Core. The goal is to allow for true cross platform development with the rapidly evolving tools and APIs that we’ve come to expect from Microsoft
you know, exactly what Java promised and never delivered. Right before Oracle started suing everyone
“I didn’t search to see whether anyone else has had the same issue, so I’ll just post mine and hope for the best”
Here are some examples of questions in this category:
- What is launchSettings.json and each of its key-value pairs?
- .NET Core – Is there a way to implement WinForms?
I’ve rewritten this section a whole bunch of times, and there’s no way to write this without sounding horrid. But sometimes there are necessary evils.
These questions are usually the ones which get marked as duplicates within minutes of them being asked, and usually are deleted or abandoned within hours. The duplicate tag is required at Stack Overflow because it helps visitors and answerers from spending time with the same question over and over again
When you encounter a problem with some code that you’re writing, take a moment to think about what you’re trying to achieve. Then follow the steps that I outlined in part one of this two part series.
The chances of you having a completely unique issue are pretty slim, so taking time out to Google/Bing some keywords related to your issue if asking a colleague, co-worker or peer doesn’t yield any help
although, I’m sure that you’ll get most of the way towards an answer, if you do
is a sure fire way to finding other people who have had the same problem.
Stack Overflow has only been around since 2008, but blogs have been around since 1997
well, the word “blog” was coined in 1997 anyway
and technical forums have been around since the days of BBS and Usenet News Groups. So there’s a wealth of information out there – even for languages and frameworks which have been around for a very short time.
The point I’m getting at here, is that you should be searching before your ask a question. Even if you don’t do a Google/Bing, but search on Stack Overflow
the search function is really quite good, you know
Even if you find a question which fits your situation perfectly, but has no answers, leave a comment along the lines of “I’m having this issue, too. Except my project is…” and explain the differences between what you’re doing and what the person who posed the question is doing.
This is a pretty rough post to read, I’m sure that you’ll agree. But it’s one that I’ve felt that someone has had to write, because there are so many of the same questions coming up on Stack Overflow (and the like) which go unanswered.
I haven’t wanted to call anyone out directly, but I’ve had to give examples. I’ve asked stupid questions in the past, as I’m sure everyone has
just me? fair enough
Hopefully, this post hasn’t come off as vitriolic or nasty in anyway.