Thursday, January 5, 2017

Before moving on I am assuming that you have the basic knowledge on .NET Core and application development targeting .NET Core.

In this post let’s see how we can do a Self-Contained Deployment (SCD) on a Ubuntu machine where there is no .NET Core SDK is installed.

So basically that’s the most important aspect of doing a SCD, we are no longer dependent on a machine wide framework. Framework is bundled with the our application (and third party dependencies if any) and it will get run on top of that. Where as in FDD (Framework-Dependent Deployment), we are deploying only the application (and third party dependencies if any). The application will get run on top of the framework which is installed on the machine.

(Some important thing to note here, in .NET Core Application Deployment documentation under SCD it says, "Creating an SCD does not, however, include the native dependencies of .NET Core itself on various platforms (for example, OpenSSL on macOS) so these need to be installed before running the application.". So there is a list of dependencies for Ubuntu and I have not installed any of those. I was confused about that. Thanks to fellow MVP @WilliamIvanski, I got some explanation from him. His explanation is as follows,

"-dev packages contain headers that allows one to recompile software that depend on these libraries. If you need to only run such software, the package without -dev may be installed. For example, libicu/libicu{somenumber} may be already installed. That's why your application runs fine. You'll need *-dev packages if you want to compile dotnet itself. ". Well that answered my question. When I checked for those packages, they were already installed upon OS installation.)

Here let’s start by creating a Console Application targeting .NET Core. I am using Visual Studio 2015 Update 3.(You need to note that for this demo, I am using the latest stable versions of tools and frameworks as of today. There is a possibility that some of this will get changed in the future. For instance, I will be using project.json and it will get removed in Visual Studio 2017. But all we really need to do is understanding the concept.)

Console Application (.NET Core)

Having said that, I have created the project. This is what my default project.json looks like (this may be different from yours and it is based on the version of .NET Core tools that you have installed).

Now let’s do the changes which is required to make this application to be deployed as SCD.

{

"version": "1.0.0-*",

"buildOptions": {

"emitEntryPoint": true

},

"runtimes": {

"ubuntu.16.04-x64": {}

},

"dependencies": {

"Microsoft.NETCore.App": {

"version": "1.1.0"

}

},

"frameworks": {

"netcoreapp1.1": {

}

}

}

Here, first thing I did was removing the type=”platform” element. That is what specifies whether this is going to be a SCD or FDD. Here I have also specified the Ubuntu runtime (my Ubuntu installation is 16.04.1) as it’s mandatory when doing a SCD. You can find the list of .NET Core Runtime IDentifiers (RID) here).

Now I have modified program.cs to print "Hello World" to the console. Nothing fancy over there.

publicclass Program

{

publicstaticvoid Main(string[] args)

{

System.Console.WriteLine("Hello World");

}

}

Now let’s move into dotnet CLI, and do the build and release. I am not going to run dotnet restore, as I was using Visual Studio and it was doing the package restoration upon project.json changes for me. If you are on VS Code or other editor run dotnet restore to restore the packages.

To build the application against my targeted runtime, I am running the following command.

dotnet build -r ubuntu.16.04-x64

Result: Build

Now to create the release package, I am running the following command.

dotnet publish -c Release -r ubuntu.16.04-x64

Result: Release

You can see that a folder named publish has been created under {project}\bin\Release\netcoreapp1.1\ubuntu.16.04-x64.

Now you just need to copy/move the publish folder into a Ubuntu machine. I have done that and here it is.

Published folder on Ubuntu

Now open up a terminal. You can see that I have not installed .NET Core over there.

dotnet

Now let’s try to run the application.

Running the application

Here I am thrown with an error “Failed to initialize CoreCLR, HRESULT: 0x8007001F”. And found out this was caused by a permission issue.

Let’s try giving all the permission to the executable and try back again.

Tuesday, January 3, 2017

If you are on Visual Studio 2015 and if you are working on .NET Core related projects, I am sure you are familiar with the project.json file.

In this post let’s see the difference between having dependencies section global Vs. nested under frameworks section in the project.json. And that’s basically the difference between following.

"frameworks": {

"netcoreapp1.1": {

}

},

"dependencies": {

"Microsoft.NETCore.App": {

"version": "1.1.0"

}

}

Vs.

"frameworks": {

"netcoreapp1.1": {

"dependencies": {

"Microsoft.NETCore.App": {

"version": "1.1.0"

}

}

}

}

Here in the second, dependencies section is nested under frameworks section. In both of these scenarios packages are getting restored without any errors. So are these the same, if not, what is the difference?

There is a significant difference between these two approaches. To give you all a better explanation, let’s change the first example, adding another framework which the application will support, say .NET Framework 4.5.2.

"frameworks": {

"netcoreapp1.1": {

},

"net452": {

}

},

"dependencies": {

"Microsoft.NETCore.App": {

"version": "1.1.0"

}

}

With this change, packages are not going to get restored any more, it will throw you an error “The dependency Microsoft.NETCore.App 1.1.0 does not support framework .NETFramework,Version=v4.5.2”.

So what is happening here is when you defined dependencies as global, that means all those listed should able to be used with all the different frameworks your application supports. In this case, Microsoft.NETCore.App does not support .NET Full Framework as it contains APIs that targets .NET Core.

So the best practice is, if your application supports multiple frameworks, list the common dependencies in global dependencies section and if you have framework specific dependencies, list them inside dependencies section under frameworks section. For instance that would be something like below,

"frameworks": {

"netcoreapp1.1": {

"dependencies": {

"Microsoft.NETCore.App": {

"version": "1.1.0"

}

}

},

"net452": {

}

},

"dependencies": {

"Newtonsoft.Json": "9.0.1"

}

If your application supports only one framework, you can either list them under global dependencies section or list them inside dependencies section under frameworks section as both are fine.

Sunday, January 1, 2017

It’s always one of the nicest feelings to start writing the first blog post of the new year with this one. I am humbled, pleased and honored to receive the precious Microsoft Most Valuable Professional (MVP) Award for the fourth consecutive year. Like last year got the award under Visual Studio and Development Technologies. In the first two years, I have been awarded MVP for Visual C# and then .NET.

As always looking forward for another busy year on top of Microsoft Development Stack.