What should you know about .NET Core?

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

.NET Core is new big thing in .NET universe, no question. However, there many .NET streams out there and it is not easy to make right decisions, which will hold for years or decades. This post describes few basic, but very important steps when developing applications with .NET Core. I will show how to create an application and a library. Then I will target different frameworks and finally build some unit tests in the way which is not very common in .NET community as probably many other things, which you will read here.

How to create application in Visual Studio?

Easiest way to create an application in .NET Core is using Visual Studio.

image

That creates common application with a new artifact ‘project.json’ file, which describes the project. Please remember, innovation of project.json is not in moving from XML to JSON. Old XML project file was tightly coupled to visual studio. new project.json file is decoupled from Visual Studio and it is a consisted part of .NET Framework. 
Choosing JSON instead of XML has no any value added. It is just influenced by coolness factor of JSON (at least in theses years).

image

How to Create and reference a library in Visual Studio?

To create a library we use Class-Library template, as usual.

image

 

image


Let’s add now a reference to new library from our executable Sample01.

image

By default .NET core use NUGET to reference packages from external projects. By adding a reference to project ClasLibrary1, VS will add reference to the project, but project.json will try to resolve it as a NUGET package. Because we didn’t create a package we will get error shown at the picture above (NU1001).

To fix it, open the project.json file of the project which is referencing the library (In my case ‘Sample01’) and lookup following entry:

image

We need to tell VS ,that we want to reference the library as a project and not as NUGET package.

image

After that build will still report the same error. To make it finally working we have to restore NUGET packages:

image

While restoring VS will show on top-right restoring indication.

image

If you don’t like this, you can switch it of in VS .NET Core settings:

image

This was easy going, because both Sample01 and ClassLibrary1 was created from set of new .NET Core templates. This is lucky case. In the real life we will have to deal with dependencies, which targets different versions of .NET framework.

.NET Core Application Types

One more important note. project.json file specifies a dependency to “Microsoft.NETCore.Appnuget package.

image

This is a set of .NET API's that are included in the default .NET Core application model. The type: platform property on dependency above means that tooling, at publish time, have to skip publishing the assemblies for that dependency to the published output. You don't need them if you expect they will be installed with .NET Core on the targeted machine.

Applications that require .NET Core to be installed on the targeted machine in order to run are called Portable Applications.

Another type of .NET core application is Self Contained Application. These applications have to specify exact runtime, which they will use. To do that you have to specify a runtime in project.json file:

{
 
"version": "1.0.0-*"
,
 
"buildOptions"
: {
   
"emitEntryPoint": true

  },

 
"testRunner": "xunit",
 
"dependencies"
: {
   
"ClassLibrary1"
: {
     
"target": "project"
,
     
"version": "1.0.0-*"

    },
   
"dotnet-test-xunit": "2.2.0-preview2-build1029",
   
"Microsoft.NETCore.App"
: {
     
"type": "platform"
,
     
"version": "1.0.0"

    },
   
"xunit": "2.2.0-beta2-build3300"
  },

 
"frameworks": {
   
"netcoreapp1.0"
: {
     
"imports": [ "dnxcore50", "portable-net45+win8"
]
    }
  },
 
"runtimes"
: {
   
"win10-x64"
: {},
   
"osx.10.11-x64"
: {}
  }
}

 

I added two runtimes, which are on next restore installed on your development machine (see next topic for more information about install location).
To publish your self-contained application execute following command:

dotnet publish --runtime win10-x64 

image

Last, but not least self-contained applications are independent, but occupies more space. For example one runtime occupies approximately 1-5 MB (at the moment – not optimized).

How about different Runtimes?

In the previous topic we have described different standards and different versions of .NET Framework. But we should not forget runtimes. Runtime is smallest subset of functionalities and type system, required to run on a specific operative system. Frameworks are built on top of runtimes. An example of runtime is “win7-x64” “win7-x32”, "osx.10.11-x64” etc. To specify a correct runtime, .NET framework use following notation:

       [os].[version]-[arch]

That string defines an identifier called RID (Runtime IDentifier). It represents the concrete operating system. The list of all supported runtimes can be found

https://github.com/dotnet/corefx/blob/master/pkg/Microsoft.NETCore.Platforms/runtime.json

Interestingly, in project.json created by VS templates, does not contain any runtime reference. This is because VS targets by default portable .net core application type. It means application requires correct runtime to be installed on the machine independent on application.

Once you reference some runtime in your projec.json file and do restore of packages, dotnet tool will install them under user hive as shown at following picture:

image

Working with different standards and versions of .NET framework

Once the library is created, open project.json of the ClassLibrary1 and look for

"dependencies": { "NETStandard.Library": "1.6.0" },

But, what NETStandard.Library does mean? That name is so called Target Framework Moniker or shortly TFM. It is always followed by some version number.

The .NET Standard Library is a formal specification of .NET APIs that are intended to be available on all .NET runtimes.
Standard library:

  • Defines uniform set of BCL APIs for all .NET platforms.
  • Enables developers to produce portable libraries that are usable across .NET runtimes, using this same set of APIs.
  • Reduces conditional compilation of shared source due to .NET APIs, only for OS APIs.

.NET Standard Library is versioned set of reference assemblies that ALL .NET Platforms must support as defined. This library is defined in the CoreFX repository. In the new world of .NET universe, we can think about it as Portable Class Library vNext.

To get a better feeling about relations between different version, take a look on following table.

image

As you see .NET Core 1.0 and .NET 4.6.3 implements same set of libraries in .NET Standard Library 1.6. This is a huge step forward. Unfortunately, big disadvantage is that UWP targets .NET Standard v1.4 only, which might make some difficulties to target Windows 10 devices on UWP.
Another important fact, you have to be aware of is that .NET cannot be ported to any of .NET standards. That means, if you have PCL build with profile portable-net40+sl5+wp80+win8+wpa81, that one cannot be retargeted to .NET standard. But if you would have a PCL portable-net45+wp80+win8+wpa81+dnxcore50, we could retarget it to .NET Standard1.0.
In other words, every assembly built with 4.5 or older version (as mono) cannot be retargeted to any .NET standard.

To get a bit better feeling how all this behaves, let’s build a Win32 (Desktop) console application, which will reference ClassLibrary1. Create a new project and be sure that you chose Windows/Console Application. Do not chose .NET Core/Console Application as in previous example.

image

As next, let’s reference the ClassLibrary1 from new Console Application. Some of you might be suppressed, because this will not work.
You will get following error:

image

That means, VS still does not recognize template of the .NET Core project. But this will be fixed soon, I guess.
We have two choices at the moment to reference the library from Win32 (Desktop) application:

- Add reference directly to assembly
- Add reference to package. (At the end of this article I will show how to create NUGET package.

I will add a reference directly to assembly, but before I do that I have to be sure which version of .NET Framework uses my Desktop Console Application.
If my application uses .NET 4.6.1 then I can only reference assemblies, which uses .NET Standard Library 1.4. I know this, if I take a look in a table shown above.
However, our ClassLibrary1 is build with support to v1.6.0. (take a look in project.json)

 "dependencies": { "NETStandard.Library": "1.6.0" },

The table below shows that 4.61 of .NET Framework is not compatible with .NET Platform Standard 1.6

image

If we try to do that, following exception will be thrown (at least):

An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
Additional information: Could not load file or assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

To workaround this, there must be a build of a ClassLibrary1, which supports standard 1.4. To achieve this we need to extend project.json as shown below:

{

  "version": "1.0.0-*",

 

  "dependencies": {

    "NETStandard.Library": "1.6.0"

  },

 

  "frameworks": {

    "netstandard1.4": {

      "imports": "dnxcore50"

    },

    "netstandard1.6": {

      "imports": "dnxcore50"

    }

  }

}

After this change, we need to add a reference to DLL v1.4 from Console Application.

How to create a Unit Test project?

As unit test engine, I will use XUNIT. Let’s add XUnitTesting packages ‘xunit’ and  ‘dotnet-test-xunit’ to project ‘Sample01’. After adding a NUGET package you will have to change reference.
Lookup dnxcore50 in project.json (belov on left and replace it with import shown below on right.

imageimage

Note,  xunit  libraries have been compiled as portable library with a profile that includes "portable-net45+win8". At the moment of creating of that library .NET Core in this version was not existing. If you have been working with .NET core previously, you will probably need to change import directive too the same way as I shown it here.
Once all existing libraries are migrated to the new profile set, this will not be required anymore.

Please also activate a testRunner as shown on the picture below:

image

Finally, you will have to restore the references as already described above. 
Sample01 project looks like shown at following picture:

image

Here is my test sample:

image

Tests can be started as usual by using Visual Studio, but we can also use DOTNET-core tooling. To execute tests, navigate to project folder, which contains project.json and implementation of tests. Then execute

dotnet test

Following is the result. If there is at least one failed test, you will get result as shown below:

image

Ho to create a NUGET package

One of helpful features of .NET core is creation of NUGET packages. It is simply a part of dot net core toolset. To create a package simply use following command:

dotnet pack

Command will produce following output:

image

Package can be found in debug output folder:

image

Useful references:


- .NET Standard Library in depth: https://github.com/dotnet/corefx/blob/master/Documentation/architecture/net-platform-standard.md
- Reference Implementation on GIT: https://github.com/dotnet/corefx
- Overview .NET Standard: https://docs.microsoft.com/en-us/dotnet/articles/standard/library
- Getting started: https://docs.microsoft.com/en-us/dotnet/articles/core/tutorials/using-on-windows

Posted Jul 26 2016, 10:49 PM by Damir Dobric
Filed under:
developers.de is a .Net Community Blog powered by daenet GmbH.