30

From the wiki for the main "aspnet" GitHub repo:

"The DNX is an SDK containing all of the bits needed to build and run an application, including the CLR in the case of Core CLR. It can be bin deployed with your application...".

I'm a bit confused on what this actually means. Based on this description, and other comments I've seen in Microsoft announcements and blog posts, it would seem that you could take an ASP.NET 5 application and create a self-contained bundle with no outside dependencies. The bundle would include your code, the DNX runner, the ~11 megabyte CoreCLR, and any other NuGet dependencies you might use. "All the bits needed to run your application", ready to be dropped onto a clean slate target machine.

However, when I use dnu publish, that's not what happens. The resulting bundle contains my code, and DLL's for the pieces of the standard library that I'm actually using. However, it's not pulling in the whole CoreCLR... and it's certainly not pulling in DNX. The run command from my project.json file gets turned into a run.cmd batch file that looks like this:

@"dnx.exe" --appbase "%~dp0approot\src\ConsoleApplication" Microsoft.Framework.ApplicationHost run %*

... suggesting that DNX is expected to already be installed on the target system, outside of this bundle.

Am I missing something fundamental here? If you need DNX installed on the target system, then I'm not sure what advantages are provided by this approach at all. Is there an additional step that one can take, to publish a bundle that has DNX and CoreCLR fully baked-in and self-contained?

I see that dnu publish has an optional --native argument, but I'm not sure that this is relevant. That argument wants you to specify a runtime. When I use "clr" I get the error message, "Native image generation is only supported for .NET Core flavors". When I use "coreclr", I get this ugly stacktrace:

C:\Users\Steve\Desktop\ConsoleApplication>dnu publish --native --runtime active
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Framework.Project, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.Framework.Project, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' ---> System.IO.FileNotFoundException: Could not load the specified file.
File name: 'Microsoft.Framework.Project'
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyName(AssemblyName assemblyName)
   at System.Runtime.Loader.AssemblyLoadContext.Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
   at Microsoft.Framework.PackageManager.Publish.NativeImageGenerator.<>c.<Create>b__4_0(String r)
   at System.Linq.Lookup`2.Create[TSource](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.GroupedEnumerable`3.GetEnumerator()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
   at Microsoft.Framework.PackageManager.Publish.NativeImageGenerator.Create(PublishOptions options, PublishRoot root, IEnumerable`1 contexts)
   at Microsoft.Framework.PackageManager.Publish.PublishManager.Publish()
   at Microsoft.Framework.PackageManager.Program.<>c__DisplayClass3_2.<Main>b__4()
   at Microsoft.Framework.Runtime.Common.CommandLine.CommandLineApplication.Execute(String[] args)
   at Microsoft.Framework.PackageManager.Program.Main(String[] args)
System.IO.FileNotFoundException: Could not load the specified file.
File name: 'Microsoft.Framework.Project'
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyName(AssemblyName assemblyName)
   at System.Runtime.Loader.AssemblyLoadContext.Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
Steve Perkins
  • 11,520
  • 19
  • 63
  • 95
  • Why would you expect it to pull in the "whole CoreCLR"? The whole point of the Core CLR is that you only need to include the assemblies that your application users. Otherwise, you might as well be using the .NET Framework instead of .NET Core. – mason May 08 '15 at 02:32
  • Well, I thought the point was that the CoreCLR is only 10 to 11 megabytes or so, plus whatever additional dependencies you need. As opposed to 100+ megs for the full .NET framework, even if you app doesn't use 90% of it. Either way, the question still stands. What would be the point of bundling the core library assemblies used by an application, if the target machine still needs DNX installed (which in turn includes one or more full CLR runtimes anyway)? – Steve Perkins May 08 '15 at 03:20

1 Answers1

12

In theory, you should be able to deploy your application into a machine where even .NET Framework is not installed but I remember hearing that even the dnxcore has some .NET Framework dependencies today and will be gone later (I could be mistaken, it's worth trying this out).

Assuming this is there and you want to achieve this, you should indeed use the --runtime switch and you need to have coreclr active if you are going to pass active as value.

For example:

dnvm use 1.0.0-beta4 -r coreclr -p
Active Version           Runtime Architecture Location                       Al
                                                                             ia
                                                                             s
------ -------           ------- ------------ --------                       --
       1.0.0-beta4       clr     x64          C:\Users\Tugberk\.dnx\runtimes
       1.0.0-beta4       clr     x86          C:\Users\Tugberk\.dnx\runtimes
       1.0.0-beta4       coreclr x64          C:\Users\Tugberk\.dnx\runtimes
  *    1.0.0-beta4       coreclr x86          C:\Users\Tugberk\.dnx\runtimes

This should bundle the runtime along side your application.

tugberk
  • 57,477
  • 67
  • 243
  • 335
  • 6
    Ahh... I was close, but actually going a step too far! I was running `dnu publish --native --runtime active`. I only used the `--runtime` argument because it was called for by the `--native` argument. It didn't occur to me to go in the opposite direction, and try using `--runtime` WITHOUT `--native`. When I do that, then DNU copies the entire `dnx-coreclr-win-x86.1.0.0-beta4` folder into my output bundle's `approot\packages` folder... and the `run.cmd` batch file references `dnx.exe` within this embedded CLR, rather than expecting it to be on the system PATH. – Steve Perkins May 08 '15 at 09:23
  • The ASP.NET 5 documentation could definitely use more meat on its bones, but of course it's still in its very early days and I'm sure things are yet to change (e.g. half of the information I've found still refer to pre-rename commands like `kvm` rather than `dnvm`, etc). I'm still completely baffled about the `dnu publish --native` argument that I was trying... what's it supposed to do? – Steve Perkins May 08 '15 at 09:24
  • `--native` generate the native images for CoreCLR. By using native images you get a performance boost – Victor Hurdugaci May 08 '15 at 15:49
  • @StevePerkins [.NET Native](https://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx) takes MSIL code and compiles it to machine specific code. Meaning that no JIT compiling needs to be done, leading to the performance boost that Victor mentioned. The disadvantage is that you'll end up with separate assemblies for each machine targeted (X86, X64, ARM 32bit etc). But that's merely a distribution problem. – mason May 09 '15 at 17:01
  • @mason @Victor Hurdugaci - My understanding is that .NET Native is only relevant to Windows 10 Universal apps. Is that still correct, and if so then does it mean that the `--native` argument is likewise only relevant to Windows 10 Universal apps? Is full ahead-of-time compilation possible for web applications or traditional desktop apps? – Steve Perkins May 11 '15 at 00:51
  • @StevePerkins .NET Native currently only works with WinRT apps, but their goal is to eventually bring it to ASP.NET and the rest of .NET. I believe that was mentioned at one of the Microsoft conferences, and it's also answered here: https://msdn.microsoft.com/en-US/vstudio/dn642499.aspx – mason May 11 '15 at 00:58