The Era of Portable .NET

portable_dotnet_header

The .NET framework has had quite the journey from conception until today. Yet, every iteration from .NET 1.0 to .NET 4.5, almost invariably required kittens to die, as you painstakingly upgraded your apps and the .NET runtimes. The challenge, in part, was because of the giant monolithic .NET framework that all your apps depended on.

All that changes moving forward.

The new .NET framework is modern, lean, modular and open source. No longer is .NET a system-wide installation – it is merely a folder. Instead of a huge underlying framework, you only pick and choose the pieces of the .NET framework that you need in your apps. And more importantly, you can package the required components of the .NET framework right alongside your app. We’re entering an age of app-runtime silos and ultimate portability.

This article shows you .NET’s portability with modern ASP.NET web applications.

DotNETSourceMeme

The new .NET depends on the .NET CLI. You can learn more about the .NET CLI check out our whitepaper, The Command Line: Reinvented for Modern Developers.

ASP.NET Leading Charge

Not surprisingly, ASP.NET 5 is driving many of the changes in .NET, as shown in the 10K feet view below. ASP.NET 4.6 is the next full iteration of ASP.NET and it runs on the full API canvas of .NET 4.6 – everything you do now in .NET runs just fine in this mode going forward. The new kids on the block are ASP.NET 5 and .NET Core 5 – both of them lean, modular, cross-platform and open source.

DotNetPicture

You may call this an effort to democratize .NET and ASP.NET for every type of developer. Gone are the days of high barrier to entry, massive installations and IDE lock-ins – you should be able to use ASP.NET 5 on any platform and using any editor of your choice.

To make things easy, there is now get.asp.net – a simple place to get all that you need to build and run ASP.NET 5 applications. Here’s what you see on a Mac.

GetASPOnMac

And here is what you see on Windows.

GetASPOnWindows

As you can see, you get contextual buttons to install the appropriate versions of .NET. On Windows, you are offered a choice of ASP.NET 4.6 and 5, while on a Mac, it is simply the cross-platform ASP.NET 5. When you click on the big green buttons the correct .NET runtime components are installed – DNX and DNVM.

DNX is the heart of the new .NET – the runtime environment that bootstraps your apps. It provides a host process, CLR hosting logic and managed entry point discovery towards running .NET apps on any platform.

DNVM, on the other hand, is the .NET Version Manager. It is a set of command line tools that configure and update the .NET framework runtimes you use within your apps. And since you can now bundle the .NET runtime with your apps, DNVM plays a critical role in keeping the runtime silos side-by-side, yet independent.

The installers from get.asp.net will set up DNX and DNVM on your machine. Almost as a direct response to my rant against bloated software, DNX installations are now a piece of cake – a mere 46 MB!

DNXInstallSizes

Once your installations finish, pull up the command prompt on Windows, OSX or Linux and enter the command $ dnvm list. This will list out all of the DNX runtimes you have installed previously on your machine, along with an indicator of the active version.

DNXVersionsOnMac

Portability between Windows

You may keep hearing that the new .NET is open source and cross-platform. One question you may have is: is it also portable? Can I build a .NET app on one Windows machine and run it seamlessly on another Windows machine, without having to install or configure anything on the second machine? The answer is an emphatic “yes.”

App Components

Let’s try out .NET’s portability with a simple ASP.NET 5 web app. You can start with the boilerplate ASP.NET project template in Visual Studio 2015, as below.

NewProject

Once your project is created, take a look at the References folder. You’ll see two things: DNX 4.5.1 for .NET 4.6 and DNX Core 5.0 for .NET Core 5. These list all of the components of the .NET framework that your app is using.

The most radical change? They are all NuGet packages! No longer are you adding direct references to dependencies. Instead, the core parts of the .NET framework are being brought in as NuGet packages that are easy to configure, maintain and update.

NugetRefs

By default, ASP.NET 5 apps can run on both .NET 4.6 or .NET Core 5. You can control and choose the runtime, either from the Project Properties or through the Project.JSON file.

TargetDNX

DNX is what will actually run your ASP.NET web app, and the different versions will be tucked away in the .DNX/Runtimes folder under your User account.

This is a breath of fresh air – .NET is no longer a system wide installation. The runtimes are merely portable folders!

WinDNXList

Fire up the $ dnvm list request in your command line, and DNVM will list out the DNX runtimes that match what you see in your folder.

WinDNXListCommand

Now that you know where DNX lives, just let it run your ASP.NET web app. If you come back to Visual Studio and fire up F5, you get the normal build/deploy experience and the familiar ASP.NET templated solution.

WebAppInWindows

Publish from Visual Studio

Now that your ASP.NET 5 app runs fine locally, how do you make it portable? Can you simply bundle it up in a package and run it on any other Windows machine? Yes, using the Publish wizard in Visual Studio.

Right-Click on your project and select Publish to bring up the wizard. You can publish to the cloud, but in this case, you want to make the app portable – so choose the File System option.

PublishWizard

The wizard will ask for a Target Location – this is the output directory where your app will be bundled up.

PublishLocation

The last step of the Publish wizard asks for the version of DNX you want to include with your app. This is truly packing up everything about the .NET framework that is needed to run your particular app. The drop-down conveniently pulls up a list of available DNX versions available on your machine.

PublishDNXOptions

The Publish script depends on having NodeJS, Bower & Gulp installed on your machine. If anything fails, ccorrectly configure these three and try again.

VSPublish

Once the process is complete, take a look at your output directory or the target location. The wwwroot subdirectory contains all your static assets for the ASP.NET app.

VSPublishFolder

The approot subdirectory contains your application source code, packages and dependencies – everything needed to bootstrap and run your ASP.NET app, all in one place.

VSPublishApproot

Did you notice the ef and web scripts in the approot folder? Those correspond directly to the two commands you have from the default Project.JSON file in your project – these are simple scripted shortcuts to execute those commands from the command line.

ProjectJSon

That’s all. Simply copy the entire generated folder at the target location onto a USB drive, do cloud sync or perform some other means to transport the app onto another Windows machine. No installs or configuration are necessary. Simply run the web command script – and, voila, you can run the ASP.NET web app (http://localhost:5000 in browser) just as if it was built natively on the second machine. Pretty cool.

Cross-Platform Portability

You know what’s cool? Being able to use Windows, OSX and Linux interchangeably as a developer. Your choice of OS and developer tools should not matter going forward. You’ll be able to build and run .NET apps anywhere.

This also means being able to build a .NET app on Windows and run it seamlessly on OSX/Linux. This isn’t a daydream – it’s happening right now with ASP.NET 5 and .NET Core 5. Let’s see how.

Get DNX for Darwin

Although .NET CoreCLR is completely open source and cross-platform, the runtime versions tend to be a little different between OS choices, for now. And since you are packaging up the .NET framework alongside your app, you need to get the right one for portability.

Trivia: Did you know that Darwin was the historic codename for what we call OSX today? Interestingly, the DNX runtimes for OSX are marked as Darwin – maybe this a subtle hint towards a treacherous past evolving into a harmonious future.

To make your apps portable to OSX, you would need to get the DNX version meant for Darwin, as in the NuGet package below.

DarwinNuget

You could get the NuGet package through Visual Studio, but DNVM does not seem to recognize the installation. So fire up the command prompt and type in the following command:

$ dnvm install latest -r coreclr -OS darwin -a x64

What you are essentially asking DNVM to do is install the latest CoreCLR version of DNX for the Darwin OS and x64 architecture. You could also directly ask for installation of the specific the DNX version, if you have the exact details – dnx-coreclr-darwin-x64.1.0.0-rc1-update1 for now. You should see the runtime installation being pulled down from the NuGet server.

InstallingDarwinRT

Once install completes, head back to your .DNX/Runtimes folder and the CoreCLR DNX for Darwin shows up. Pull up the command prompt and enter $ dnvm list, and the DNX version for Darwin should now be ready and listed on your machine.

UpdatedWinDNXList

UpdatedWinDNXListCommand

Package It Up

Once you have the correct DNX runtime to make your ASP.NET app portable to OSX, next comes the packaging. The Visual Studio Publish wizard does not quite pick up the installed Darwin DNX. So you may have to fall back to a more sure-shot way – the all-powerful command line.

This time, a command called DNU (DotNetUtilities) comes in handy. For example, here’s the command I used with my specific project/output folders:

$ dnu publish "C:\Code\PortableASPNet\src\PortableASPNet" --out "C:\Web Apps\PortableASPNet" --configuration Release --runtime dnx-coreclr-darwin-x64.1.0.0-rc1-update1`

This command essentially says – take the project with the specified runtime and publish the build output to the target location. Once finished, feel free to check on the taget directory’s approot/runtime folder. The packaged runtime now contains the DNX version meant for Darwin!

PackagedRT

Portability on a Stick

Now for the magical part of moving your ASP.NET web app from Windows to a Mac. Grab the entire generated folder and put it on a USB stick. Take it to a Mac and open it up, as shown below. You should be seeing the same approot, logs and wwwroot folders, with approot containing the source code along with command scripts.

AppOnStick

Just for sanity’s sake, take a peek inside the runtimes folder – this should house the DNX Darwin runtime, a few DNU tools and every piece of the .NET framework that is required for your app. Yes, you’ll see DLLs from the .NET world that will now power your app on a Mac.

PackagedRTonMac

Ready for the ultimate party trick? Just fire up the generated web command as ./web or dnx web from inside the USB storage folder. Then head over to your browser and pull up http://localhost:5000 (the port number is controlled by ini file). And there you have it – an ASP.NET web app built on Windows, running seamlessly on a Mac off of a USB folder. How mind-blowing is that?

WebAppInMac

PS: Big thanks to my good friend Shayne Boyer for help with this article.

Conclusion

The .NET framework has a new promise – a lower barrier to entry without artifical platform borders. Pick your OS and development tools of choice. You should be able to build and run .NET applications on any platform.

And with a modular design and portable runtime components that can be packaged up along side your app, you have complete freedom to move your applications from one machine to another. Relish the flexibility and go build your next amazing app!

Need some oomph for your next ASP.NET web app? Tired of re-inventing UI components? Try the Telerik UI for ASP.NET MVC suite for free – you get 70+ polished and performant UI widgets and framework components for modern web apps. And UI for ASP.NET MVC fully supports VS 2015 and is compliant with the latest ASP.NET 5/MVC 6 RC builds – as ready and bleeding-edge as you are. Have fun!

Lunchbox header image courtesy of Mike Licht

UI for ASP.NET MVC

Comments

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1992()

  • Ray

    Can we now run vb.net desktop application in mac ?

    • Samidip Basu

      Ray – not yet. In future, we could arguably see desktop apps running on top of .NET Core and hence X-Plat. Let’s stay tuned.

  • Mergete

    Can’t wait for a simple WPF package for OSX!

    • Samidip Basu

      Mergete – Yeah, me too. We’re just not quite there yet.

      • Mergete

        I’ve used Eto.Forms (https://github.com/picoe/Eto) and it’s great – but it would be awesome to use WPF as the part of a bigger ecosysteme.

  • Andrew Stephens

    Does this also apply to desktop applications (WPF in particular)?

    • Samidip Basu

      Andrew – Afaik, not yet. But arguably in the near future, we could see WPF apps running on top of .NET Core and hence X-Plat. Let’s stay tuned.

  • Mohsen Afshin

    Thank you for sharing information

    • Samidip Basu

      Mohsen – you’re most welcome! Please let us know what cool apps you build with the new .NET or ASP.NET.

      • Mohsen Afshin

        Not yet but I’m going to try .NET Core on Raspberry 2

  • Pingback: Automate the Planet()

  • Pingback: The week in .NET - 12/22/2015 - .NET Blog - Site Home - MSDN Blogs()

  • Good news to know. Maybe will be useful to known how many resources are requested to compile the ASP.NET and .NET Core modules, and so know if them can be deployed to low-profile hardware like the raspberry or Intel Edison.

    By the way…
    Darwin is the name of the MacOS X kernel. It’s currently actively developed as an open source standalone project, because MacOSX is based also on FreeBSD. The Darwin alone can be downloaded from Apple opensource site, and many forks exists. Usually uses GNOME as his windows manager.

  • Pingback: The Era of Portable .NET | Ramblings of a Modern Developer()

  • Pingback: The week in .NET – 12/22/2015 | .NET Blog()