I like getting great questions in email but I LOVE getting great questions in email with a complete and clear code repro (reproduction) that's in a git somewhere. Then I can just clone, build (many many bonus points for a clean build) and check out the bug.
I got a great .NET Core question and repro here https://github.com/ScarlettCode/Example. I forked it, fixed it, and submitted a PR. Here's the question and issue and today's fix.
The project has a C# library project (an assembly) that is written to the .NET Standard 2.0. You'll recall that the .NET Standard isn't a runtime or a library in itself, but rather an interface. They are saying that this library will work anywhere that the .NET Standard is supported, like Linux, Mac, and Windows.
Here's that main .NET Standard Library called "Example.Data" written in C#.
Then he had:
Windows Forms (WinForms) application in VB.NET using .NET "full" Framework 4.6
Console Application also using .NET Framework 4.6
Console Application using .NET Core 2.0
Each of these apps is referring to the Example.Data library. The Example.Data library then pulls in a database access library in the form of Microsoft.EntityFrameworkCore.InMemory via NuGet.
WinForms app -> Data Access library -> Some other library. A->B->C where B and C are packages from NuGet.
The .NET Core console builds and runs great. However, when the other projects are run you get this error:
Can't load Could not load file or assembly 'Microsoft.EntityFrameworkCore, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.
Pretty low level error, right? First thing is to check the bin folder (the results of the compile) for a project that doesn't run. Looks like there's no Microsoft.EntityFrameworkCore there. Why not? It's assembly "C" downstream of "A" and "B". EntityFramework's assembly is referred to by the Example.Data assembly...but why didn't it get copied in?
The "full" Framework projects are using the older .csproj format and by default, they use package.config to manage dependencies. The newer projects can reference Packages as first-class references. So we need to tell ALL projects in this solution to manage and restore their packages as "PackageReferences."
I can open up the .csproj file for the Framework projects and add this line within the first <PropertyGroup> like this to change the restore style:
"Using .NET Standard requires you to use PackageReference to eliminate the pain of “lots of packages” as well as properly handle transitive dependencies. While you may be able to use .NET Standard without PackageReference, I wouldn’t recommend it."
I can also change the default within VS's Package Management options here in this dialog.
Hope this helps.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
I'm working on this slide as support for this excellent .NET Glossary. It's not done yet, but I'm curious for your thoughts. Every system has terms and concepts that are initially unfamiliar but make sense once you grok them.
Here are these concepts used in an example sentence, for context:
Application Framework - “Are you using the ASP.NET Core web framework for that microservice?”
Metapackage - “I want to install the ASP.NET Core framework; it’s a package of packages”
Package/NuGet - “I know there’s a NuGet package for decoding JSON.”
Library/Assembly - “Now, you’ll compile your source into an assembly”
.NET Standard – “Which version of the .NET Standard specification does your assembly target?"
"My Apple Watch supports .NET Standard 1.6 but my Windows 10 laptop supports 2.0 with more APIs.”
C#, F#, VB, etc – “Which language did you use?”
.NET SDK - “Did you get the developer tools?”
CLR/CoreCLR – “Which runtime is your app using?”
An implementation of .NET is a runtime along with libraries that implement a version of the .NET Standard
“Are you using .NET Core, .NET Framework, or Mono for this project?”
Platform - An operating system and some hardware (ARM, x64, etc.)
“Is that an ASP.NET Core app running in Docker on a Raspberry Pi?”
Constructive feedback, please. This is a draft.
Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
I dig everything that Paul Betts does. He's a lovely person and a prolific coder. One of his recent joints is called Refit. It's a REST library for .NET that is inspired by Square's Retrofit library. It turns your REST API into a live interface:
public interface IGitHubApi { [Get("/users/{user}")] Task<User> GetUser(string user); }
That's an interface that describes a REST API that's elsewhere. Then later you just make a RestService.For<YourInterface> and you go to town.
var gitHubApi = RestService.For<IGitHubApi>("https://api.github.com");
var octocat = await gitHubApi.GetUser("octocat");
That's lovely! It is a .NET Standard 1.4 library which means you can use it darn near everywhere. Remember that .NET Standard isn't a runtime, it's a version interface - a list of methods you can use under many different ".NETs." You can use Refit on UWP, Xamarin.*, .NET "full" Frameowrk, and .NET Core, which runs basically everywhere.
Sure, you can make your own HttpClient calls, but that's a little low level and somewhat irritating. Sure, you can look for a .NET SDK for your favorite REST interface but what if it doesn't have one? It strikes a nice balance between the low-level and the high-level.
I'll give an example and use it as a tiny exercise for Refit. I have a service that hosts a realtime feed of my blood sugar, as I'm a Type 1 Diabetic. Since I have a Continuous Glucose Meter that is attached to me and sending my sugar details to a web service called Nightscout running in Azure, I figured it'd be cool to use Refit to pull my sugar info back down with .NET.
The REST API for Nightscout is simple, but doe have a lot of options, query strings, and multiple endpoints. I can start by making a simple interface for the little bits I want now, and perhaps expand the interface later to get more.
Where "sgv" is serum glucose value, or blood sugar.
Starting with .NET Core 2.0 and the SDK that I installed from http://dot.net, I'll first make a console app from the command line and add refit like this:
C:\users\scott\desktop\refitsugars> dotnet new console C:\users\scott\desktop\refitsugars> dotnet add package refit
Here's my little bit of code.
I made an object shaped like each record. Added aliases for weirdly named stuff like "sgv"
COOL SIDE NOTE: I added <LangVersion>7.1</LangVersion> to my project so I could have my public static Main entry point be async. That's new as many folks have wanted to have a "public static async void Main()" equivalent.
After that it's REALLY lovely and super easy to make a quick strongly-typed REST Client in C# for pretty much anything. I could see myself easily extending this to include the whole NightScout diabetes management API without a lot of effort.
using Newtonsoft.Json; using Refit; using System; using System.Collections.Generic; using System.Threading.Tasks;
You should definitely check out Refit. It's very easy and quite fun. The fact that it targets .NET Standard 1.4 means you can use it in nearly all your .NET projects, and it already has creative people thinking of cool ideas.
Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
"WebAssembly or wasm is a low-level bytecode format for in-browser client-side scripting, evolved from JavaScript." You can easily compile to WebAssembly from C and C++ today...and more languages are jumping in to include WebAssembly as a target every day.
Since I work in open source .NET and since .NET Core 2.0 is cross-platform with an imminent release, it's worth exploring where WebAssembly fits into a .NET world.
Here's some projects I have identified that help bridge the .NET world and the WebAssembly world. I think that this is going to be THE hot space in the next 18 months.
Despite its overarching name, this OSS project is meant to consume WASM binary files and execute them from within .NET assemblies. To be clear, this isn't compiling .NET languages' (C#, VB.NET, F#) into WebAssembly, this is for using WebAssembly as if it's any other piece of resuable compiled code. Got an existing WASM file you REALLY want to call from .NET? This is for that.
Interestingly, this project doesn't spin up a V8 or Chakra JavaScript engine to run WASM, instead it reads in the bytecode and converts them to .NET via System.Reflection.Emit. Interesting stuff!
One of the great things happening in the larger .NET Ecosystem is that there is more than one ".NET" today. In the past, .NET was a thing that you installed on Windows and generally feared. Today, there's .NET 4.x+ on basically every Windows machine out there, there's .NET Core that runs in Docker, on Mac, Windows, and a dozen Linuxes...even Raspberry Pi, and Mono is another instance of .NET that allows you to run code in dozens of other platforms. There's multiple "instances of .NET" out there in active development.
The first one uses the traditional full static compilation mode of Mono, this compiled both the Mono C runtime and the Mono class libraries along with the user code into WebAssembly code. It produces one large statically compiled application. You can try this fully statically compiled Hello World here. The full static compilation currently lives here.
So that's a totally statically compiled Hello World...it's all of Mono and your app into Web Assembly. They have another prototype with a difference perspective:
The second prototype compiles the Mono C runtime into web assembly, and then uses Mono’s IL interpreter to run managed code. This one is a smaller download, but comes at the expense of performance. The mixed mode execution prototype currently lives here.
Here they've got much of Mono running in Web Assembly, but your IL code is interpreted. One of the wonderful things about Computer Science - There is more than one way to do something, and they are often each awesome in their own way!
With a similar idea as the Mono Project's second prototype, Steve Sanderson took yet another "instance of .NET," the six year old open source DotNetAnywhere (DNA) project and compiled it into Web Assembly. DNA was an interpreted .NET runtime written in portable C. It takes standard IL or CIL (Common Intermediate Language) and runs it "on resource-constrained devices where it is not possible to run a full .NET runtime (e.g. Mono)." Clever, huh? What "resource-constrained device do we have here six years later?" Why, it's the little virtual machine that could - the JavaScript VM that your browser already has, now powered by a standard bytecode format called WebAssembly.
To prove the concept, Steve compiles DotNetAnywhere to WASM but then takes it further. He's combined standard programming models that we see on the web with things like Angular, Knockoutjs, or Ember, except rather than writing your web applications' UI in JavaScript, you write in C# - a .NET language.
Here in the middle of some Razor (basically HTML with C# inline) pages, he does what looks like a call to a backend. This is C# code, but it'll run as WASM on the client side within a Blazor app.
@functions { WeatherForecast[] forecasts;
override protected async Task InitAsync() { using (var client = new HttpClient()) { var json = await client.GetStringAsync(AbsoluteUrl("/api/SampleData/WeatherForecasts")); forecasts = JsonUtil.Deserialize<WeatherForecast[]>(json); } } }
This would allow a .NET programmer to use the same data models on the client and the server - much like well-factored JavaScript should today - as well as using other .NET libraries they might be familiar or comfortable with.
At this point it's clear that everyone is prototyping and hacking and enjoying themselves.
What do YOU think about WebAssembly?
Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
Whack Whack Terminal is an experimental free plugin for Visual Studio 2017 that aims to bring a full terminal inside of Visual Studio. Those of you who use Visual Studio Code have long enjoyed the integrated xtermjs terminal. Justin Clareburt worked with Daniel Griffen on hacking together this solution as an experiment. There is no plans for it to be more than an experiment, I'm told BUT I always say vote with your feet. I figure a few tens of thousands of installs and someone will decide to build it in. I have long used Mads Kristensen's Quake Mode that lets me launch a command prompt from VS, but ever since the NuGet Package manager showed up in VS many years ago, I've always wanted a real FULL terminal in VS.
Today, the code is alpha quality, so expect it will actively improve, and don't be mean in the GitHub Issues. They've versioned it at 0.2, and is aiming for parity with the features in the terminal in VSCode for version 1.0.
I'm sure they will update it with lots of great features like changing the fonts and colors, but if you want to hack away (as of the date of this blog post) you can mess around in C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\Extensions\sjogt3hc.qcl\daytona with ZERO WARRENTY EXPRESS OR IMPLIED. I went into there and edited the default.css file by removing all the comments and changing the background-color to black, the text to white, and adding a font-family choosing Consolas. If you do that, you'll likely need to uninstall/reinstall at some point when REAL customizations come. Again, alpha. But awesome.
"Whack" is a shorthand word for a slash (forward or otherwise) and the default hotkey is Ctrl+\, Ctrl+\. That's twice. so Ctrl WHACK WHACK. When you use the hotkey it will open the folder in the same folder as the currently selected project in the Solution Explorer.
If you want to change the hotkey to something else (like a more sensible Ctrl+~) you can do it in Tools | Options | Keyboard like this.
Then assign a new one by clicking in Press Shortcut Keys and typing "Ctrl+`" (which to me, is Ctrl ~ on my keyboard, without the shift)
By default the shell is PowerShell, but there's also places to support bash/Ubuntu, etc. For now, if you want bash, you can type C:\windows\sysnative\bash.exe in the terminal.
And just to freak you out, here's top running inside Visual Studio.
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.