RSS

Monthly Archives: January 2015

vNext and Class Libraries

This is a followup to the previous post discussing my first steps with vNext. I suggest reading it first.

vNext class libraries are similar in concept to a regular .NET library. Like ASP.NET vNext they do not actually build to a dll. What is great about them is that you can basically change the vNext library using notepad and it will be compiled on-the-fly when you re-run the page. However unfortunately code changes done in vNext, including vNext libraries, will require a restart of the host process in order to take effect. It would have been great if code changes did not require this restart and the state of the app would be maintained.

The good news is that you can reference regular .NET class libraries from vNext. This may sound trivial, but up until the recent beta 2 and VS2015 CTP 5 it wasn’t possible unless you pulled a github update and manually “k wrapped” your .NET assembly with a vNext library as explained here. Fortunately CTP 5 allows referencing a regular .NET library but it is still buggy as VS might raise build errors (as it does on my machine), but the reference will actually work and running code from a vNext MVC site actually invokes the compiled .NET dll.

Here’s how:

1. I create and open a new ASP.NET vNext web application. This time I’m using an Empty project and adding the bear minimum of code required to run an MVC app.
class lib1

project.json: Add a dependency to “Microsoft.AspNet.Mvc”.

{
    "webroot": "wwwroot",
    "version": "1.0.0-*",
    "exclude": [
        "wwwroot"
    ],
    "packExclude": [
        "node_modules",
        "bower_components",
        "**.kproj",
        "**.user",
        "**.vspscc"
    ],
    "dependencies": {
		"Microsoft.AspNet.Server.IIS": "1.0.0-beta2",
		"Microsoft.AspNet.Mvc": "6.0.0-beta2"
    },
    "frameworks" : {
        "aspnet50" : { },
        "aspnetcore50" : { }
    }
}

Startup.cs: Add configuration code and a basic HomeController like so:

using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;

namespace WebApplication3
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();
        }
    }

    public class HomeController
    {
        public string Index()
        {
            return "hello";
        }
    }
}

Running the code now “as is” should show a “hello” string in the web browser.

2. I am adding a vNext class library (this isn’t mandatory for running a .NET lib but I do it anyway for the sake of the demo).
class lib2

The class lib has a single class like so:

namespace ClassLibrary1
{
    public class vNextLib
    {
        public static string GetString()
        {
            return "hello from vNext lib";
        }
    }
}

It is now possible to “add reference” to this new ClassLibrary1 as usual or simple modify the project.json like so (partial source listed below):

	"dependencies": {
		"Microsoft.AspNet.Server.IIS": "1.0.0-beta2",
		"Microsoft.AspNet.Mvc": "6.0.0-beta2",
		"ClassLibrary1": ""
	},

Finally change the calling ASP.NET vNext web app to call the library and display the string (Startup.cs change):

    public class HomeController
    {
        public string Index()
        {
            return ClassLibrary1.vNextLib.GetString();
        }
    }

At this point I recommend to “Start without debugging” (Ctrl F5). If you don’t do that, any code changes will stop IISExpress and you’ll have to F5 again from VS. You can do that but it will not be easy to take advantage of the “on the fly” compilation.

Note the process ID in iisexpress. 2508.
class lib3

Now changing the ClassLibrary1 code to say “hello from vNext lib 2” and saving causes iisexpress to restart (note the different Process ID). A simple browser refresh shows the result of the change – no build to the Class Library was required:
class lib4

3. Now create a new Class Library, but this time not a vNext library but a regular .NET library.
class lib5

The code I use is very similar:

namespace ClassLibrary2
{
    public class RegLib
    {
        public static string GetString()
        {
            return "hello from .NET lib";
        }
    }
}

This time you can’t just go to project.json directly as before because the .NET library isn’t a “dependency” as the vNext library. You must first add a reference the “old fashion way” (VS 2015 – CTP 5, remember?):
class lib6

This automates several things:

  • It “wraps” the .NET dll with a vNext lib wrapper which can be viewed in a “src” sibling “wrap” folder. It actually performs what was previously “k wrap” from that github pull mentioned earlier:
    class lib7
  • It adds the “wrap” folder to the “sources” entry in the global.json. If you recall from the previous post, global.json references source folders for the vNext solution so this is a clever way to include references to the class lib:
    {
      "sources": [
        "src",
        "test",
        "wrap"
      ]
    }
    

Now that you have a “ghost vNext lib” wrapping the real .NET code. This isn’t enough. You need to add a dependency to the project.json just like with a regular vNext lib (you may have to build your .NET DLL first before the ClassLibrary2 is available):

	"dependencies": {
		"Microsoft.AspNet.Server.IIS": "1.0.0-beta2",
		"Microsoft.AspNet.Mvc": "6.0.0-beta2",
		"ClassLibrary1": "",
		"ClassLibrary2": ""
	},

Now changing the Startup.cs code:

    public class HomeController
    {
        public string Index()
        {
            //return ClassLibrary1.vNextLib.GetString();
            return ClassLibrary2.RegLib.GetString();
        }
    }

Now it seems like in VS2015 CTP 5 this is buggy because building results with an error that complains of a missing ClassLibrary2:

Error CS0103 The name ‘ClassLibrary2’ does not exist in the current context.

If you ignore the build error and still run using ctrl+F5 – it will work:
class lib9

Changing the regular .NET code and saving has no effect as expected, until you recompile it.

Why referencing a regular .NET lib so important? I can think of several reasons:

  1. Migrating a .NET web app to vNext. You may want to use vNext for the ASP.NET tier and use your older business logic and data layers regular .NET assemblies until you decide to migrate them.
  2. Security: If you deploy a vNext app which is not precompiled, a hacker might change your code and vNext will compile on-the-fly. You may claim that you should not deploy non-precompiled apps, but I think differently. I see it as a great advantage to be able to make changes on a server using notepad, in order to perform a quick fix or debug an issue. The downside is the potential hacking. Not sure if MS will allow a single vNext class lib to be precompiled while the rest of the site to be deployed with its source code. If not, perhaps the solution is to use a pre-compiled regular .NET class library for sensitive code, deployed with a non-precompiled vNext app.
  3. Referencing a 3rd party .NET library which does not have a vNext package might be useful.

 

Summary

I assume that Microsoft will spend more time making this wrapping mechanism transparent and flawless. Basically I see no reason why adding the dependency to the wrapping vNext lib isn’t a part of adding a reference to a .NET lib.

A good reference to vNext Class Libraries can be found in the video session of Scott Hanselman and David Fowler: http://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B411.

Advertisements
 
1 Comment

Posted by on 25/01/2015 in Software Development

 

Tags: , ,

First steps with ASP.NET vNext

This is a big topic. I have had trouble writing about this because it is so big. So I decided to split it into several blog posts. This first post is divided into several parts: intro, cool features, getting started and the K* world.

Disclaimer: Many of the stuff written here is based on beta1 and then beta2 which was released as I was into writing. Lots of stuff is bound to change including the names of the various stuff that can be seen here.

Introduction
ASP.NET 5 a.k.a vNext (temp name) is a major change to ASP.NET programming. It includes many things. This isn’t just an upgrade of several .NET assemblies, but it is also a concept change. There are quite a few resources available on the internet detailing the vNext changes in depth so instead of repeating them here I will settle for providing several references:

Cool vNext features
There are quite a few cool features but I find the following two to be most significant:

Cross Platform
The ability to run ASP.NET over Linux or Mac is a long awaited revolution (did someone just shout Mono?). Time and again I encountered customers who were opposed to use Windows based servers just because they are Microsoft’s. The option to develop .NET on a Windows machine and run it over a non-Windows server is something I really look forward to. For Windows based servers, IIS is supported but not required. Your app can also self host itself.

Yes, I am well aware of the Mono project and that it exists for years. But it makes a world of a difference to have Microsoft officially support this capability.

On-the-fly code compilation
Up until now this feature was available only to Web Site development (File->New->Web Site). In a Web Application (File->New->Project->Web) you can change a cshtml/aspx file, refresh the browser and watch the changes. But in Web Site you can also change the “code behind” files (e.g. aspx.cs), handlers, App_Code, resx files, web services, global.asax and basically everything which isn’t a compiled DLL. This allowed you to make changes on a deployed environment. This is a very important ability as it allows you to change the code using your preferred Notepad app without requiring Visual Studio and a compiler. Why is this important? Here are several examples: a) you can insert debug messages to understand a weird behavior on a production server; b) potentially fix errors on the spot without having to redeploy the entire app or a hotfix; or c) simply change a resource file. Time and again I used this ability on different servers for various purposes. In fact, to me this cool “on the fly” compilation was probably the most significant capability that made me time and again choose Web Site over Web Application. But that also means Web Forms over MVC.

On a side note, to be honest, up until now I am not convinced that MVC is a better paradigm than Web Forms. I also prefer Web Forms because of the great PageMethods/WebMethods js client proxies. Unfortunately it is clear that Web Forms will become more and more obsolete as Microsoft pushes MVC.

vNext works with MVC. Not with Web Forms. Web Forms continues to be supported for now but it will not enjoy the vNext features. But I was very thrilled to hear and see that vNext allows on the fly compilation too. Not only can you change Controllers and Models and run your software, but you can also change vNext Class Libraries and change them using your favorite Nodepad – and that – is something that you cannot do in a Web Site – you cannot change a compiled DLL using notepad! This is a very cool feature indeed, although it does made you wonder how you are supposed to protect your deployed code from hackers who may want to change your license mechanism or bypass your security. When I asked Scott Hunter about this, he replied that there is a pre-compilation module and that it will be possible to precompile the entire site. I’m not sure that it means that you can pre-compile a single assembly. Perhaps the way to over come this will be to reference a regular class library from vNext (it is doable – you can “wrap” an regular assembly as a vNext assembly and use it from a vNext app (I will demonstrate this in the next blog post).

However there is currently a difference in the on-the-fly compilation in favor of Web Site over vNext: In vNext, every change to the code (excluding cshtml) – will trigger a reset of the host. For example changing Controller code while running in IIS Express will not only restart the App Domain but will actually terminate the process and recreate a different one. This means losing any state your application may have had (statics, caching, session etc). With Web Site you can change quite a few files without losing your state (App_Code or resx files will restart the App Domain, but almost any other file change such as ashx/asmx that have no code behind or aspx.cs/ascx.cs – will work great). So making changes during development will not lose your state, or making changes on a production server – does not necessarily mean that all your users get kicked out or lose their session state. The current behavior in vNext is different and limited. I emailed this to Scott Hunter and he replied that if they do decide to support this, it’ll be most likely post RTM. I sure hope that this will be on their TODO list.

Other cool features
There are several other features which are also important. Using vNext you can have side-by-side .NET runtimes. Imagine the following scenario: you code an application using vNext and deploy it. Several months afterwards you develop another app using vNext “version 2”. You need to run both apps on the same server. Today you cannot do that because the developed apps all use the .NET installed on the same machine. An app developed to run using .NET 4 might break if you install .NET 4.5 on the same server to support a different app. With vNext you should be able to deploy your app with the .NET runtime assemblies that it was designated to be used with. More over, vNext supports a “core set” of .NET dlls for the server. So not only you do not have to install irrelevant Windows Updates (e.g. hotfixes for WPF), but the size of the deployed dlls is greatly reduced and makes it feasible to be deployed with your app.

One more feature I find interesting the the ASP.NET Console Application. What!? ASP.NET Console Application!?  Basically this means writing a Console application which has no exe. No build. The same vNext mechanism, compiling on-the-fly your vNext MVC app will be the one compiling and running your Console app. Eventually when released, perhaps vNext will not be categorized as an ASP.NET only component. vNext (or however it will be eventually named) will probably be categorized as a “new .NET platform”, capable of running MVC, Console app or whatever Microsoft is planning to release based on the on-the-fly-no-build platform. Although I did not try it, I assume that you can run a vNext Console app on a Linux or Mac (disclaimer: I haven’t yet tried running vNext on a non-Windows platform).

console


Getting started

  1. Download and install VS 2015 Preview build (http://www.visualstudio.com/en-us/downloads/visual-studio-2015-downloads-vs.aspx).
  2. Create a new vNext Web Application using File->New->Project->Web->ASP.NET Web Application. Select ASP.NET 5 Started Web with the vNext icon.
  3. After the starter project opens, notice the “run” menu (F5). It should point to IIS Express by default. Run using F5.

If all goes well, the demo website will be launched using IIS Express. Going back to VS in vNext there are several noticeable changes that can be seen in the Solution Explorer:

  • global.json: this is a solution level config file. Currently it holds references to source and test folders. I assume further solution and global projects related configuration will be placed in this file. A usage of this would be if you would like to specify external source files and packages. Taking Scott Hanselman’s example: you can download MVC source in order to fix a bug point to it locally instead of using the official release – at least until Microsoft fixes it. Personally I see myself using it to debug and step through .NET code. I have had more than enough situations struggling to understand under the hood behavior by disassembling .NET dlls and trying to figure out what I was doing wrong. As somehow the ability to download the .NET released PDBs never worked well for me, downloading the actual source code and debugging it locally seems useful. Another usage of this file is for wrapped .NET class libraries (beta2 CTP5) which I will describe in the next blog post.
  • project.json: this somewhat resembles the web.config. It contains “different kinds” of configurations, commands, dependencies etc. Dependencies are basically “packages”: NuGet packages or your very own custom vNext class libraries.
  • Static files of the website reside under wwwroot. This way there’s a clean separation from the website’s static files and the actual MVC code. (You can change from wwwroot to a different root.)
  • Startup.cs. This is the entry point in vNext. If you place breakpoints in the different methods in this file you will see that when the website starts this is indeed the starting point. Taking a look at the code in Startup.cs of the starter project you may notice that there are many things that we are used to receive for granted such as identity authentication, static files and MVC itself. In vNext we are supposed to “opt in” to the services we want, giving us full control of the http pipeline.

            // Add static files to the request pipeline.
            app.UseStaticFiles();

            // Add cookie-based authentication to the request pipeline.
            app.UseIdentity();

            // Add MVC to the request pipeline.
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index" });

                // Uncomment the following line to add a route for porting Web API 2 controllers.
                // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
            });

The K* world

An ASP.NET vNext application is not supposed to be bound to IIS or IIS Express as we are used to. In fact, it can be self-hosted and if I understood correctly, it should also run well on other platforms which are compatible with OWIN. It basically means that IIS is no longer a mandatory requirement for running ASP.NET applications. Any web server compatible with OWIN should be able to run a vNext application! OWIN:

OWIN defines a standard interface between .NET web servers and web applications. The goal of the OWIN interface is to decouple server and application

A quick demonstration of this capability is to change the “run” menu from the default IIS Express to “web” (in the starter project) and then running the web site (this is available in the latest update of the VS2015 preview – CTP5).

run menu

Notice that the running process is shown within a console window. It is the klr.exe and it is located within C:\Users\evolpin\.kre\packages\KRE-CLR-x86.1.0.0-beta2\bin. To understand what happened here we need to further understand how vNext works and clarify the meaning of KRE, KVM and K.

As previously mentioned the vNext world will have the capability to run side-by-side. It is also an open source, so you can download it and make changes. It means that development will change from what we are used to. Today when you start development you know that you’re usually bound to a specific version of the framework that is installed on your dev machine (e.g. .NET 4.5.1). In the vNext world you may have multiple .NET runtimes for different projects running on the same machine. Development could become an experience which allows you to develop alongside the latest .NET builds. Microsoft is moving away from today’s situation that you have to wait for the next .NET update to get the latest bug fixes or features, to a situation that you can download in-development code bits or the latest features without having to wait for an official release.

Getting back to the version of the framework, the KRE (K Runtime Environment) basically is a “container” of the .NET packages and assemblies of the runtime. It is the actual .NET CLR and packages that you will be running your code with (and again, you can target different versions of the KRE on the same server or dev machine).

Now that we have a more or less understanding of what is the KRE and that you may have different KRE versions, it is time to get acquainted with a command line utility called KVM (K Version Manager). This command line utility is supposed to assist in setting up and configuring the KRE runtime that you will use. It is used to setup multiple KRE runtimes, switch between them etc. Currently in the beta stages you need to download the KVM manually but I assume that it’ll be deployed with a future VS release.

To download and install go to: https://github.com/aspnet/home#install-the-k-version-manager-kvm. There is a Windows powershell command line to install. Just copy-paste it to a cmd window and within a short time KVM will be available for you to use.

kvm-install

If you open the highlighted folder you will see the KVM scripts. From now on you should be able to use the KVM from every directory as it is in the PATH. If you go to the parent folder you can see aliases (KREs may have aliases) and packages, which actually contain different KRE versions you have locally. If you open <your profile>\.kre\packages\KRE-CoreCLR-x86.1.0.0-beta1\KRE-CoreCLR-x86.1.0.0-beta1\bin (will be different if you have a different beta installed), you will actually see all the .NET stuff of the Cloud Optimized version. That 13MB is the .NET used to run your cloud optimized server code (see Scott Hunter and Scott Hanselman’s video).

Re-open a cmd window (to allow the PATH changes to take effect). If you type ‘kvm’ and press enter you’ll see a list of kvm commands. An important kvm command is ‘kvm list‘. It will list the installed KRE versions that you have ready for your account:

kvm-list

As you can see there are 4 runtime versions installed for my user account so far, including 32/64 versions and CLR and CoreCLR. To make a particular runtime active you need to ‘kvm use‘ it. For example: ‘kvm use 1.0.0-beta1 -r CoreCLR’ will mark it as Active:

kvm-list2

As you can see, ‘kvm use’ changes the PATH environment variable to point to the Active KRE. We need this PATH change to allow us to use the ‘k‘ batch file that exists in the targeted KRE folder. The K batch file allows to perform several things within the currently active KRE env (see below). In short, this is one way to switch between different KRE versions on the same machine for the current user account (side-by-side versioning.)

Just to make things a little clearer, I went to the KRE folders (C:\Users\evolpin\.kre\packages on my machine and account) and found the k.cmd batch file in each of them. I edited a couple of them: x86 CLR and CoreCLR. In each cmd file I placed an “echo” with the version and then used the ‘kvm use’ to switch between them and run ‘k’ per active env. This is what it looks like:

kvm-list3

You can upgrade the versions of the KRE by using ‘kvm upgrade‘. Note that the ‘kvm upgrade’ does not upgrade all KRE’s at once so you may have to add some command line parameters to upgrade specific KRE versions. In the example below, I have requested to upgrade the CoreCLR KRE:

kvm upgrade

After upgrading the x86 CLR and CoreCLR I found two new folders: C:\Users\evolpin\.kre\packages\KRE-CLR-x86.1.0.0-beta2 and C:\Users\evolpin\.kre\packages\KRE-CoreCLR-x86.1.0.0-beta2 as expected.

OK, so why did we go through all this trouble? As mentioned earlier, each KRE comes with the ‘k’ batch file (located for example in: C:\Users\evolpin\.kre\packages\KRE-CoreCLR-x86.1.0.0-beta1\bin). ‘k’ is used for various stuff such as running the vNext Console Apps or running the self-hosted env. Now is a good time to go back and remember that the website was last run not by IIS Express but by switching to “web” and running a self-hosted site using the klr.exe process (remember?). If we open the project.json file of the Starter project we can observe the “web” command in the “commands” section:


"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000",

This basically means that when we run the “web” command, the Asp.Net host within Microsoft.AspNet.Hosting will launch a listener on port 5000. In the command line we can use ‘k web’ to actually instruct the currently active KRE to run the “web” command like so (must be in the same folder as project.json is located or an exception will be thrown):

k web

So now we know what happened in VS when we switched to “web” in the “run” menu earlier: VS was actually running the KRE using the “web” command similar to typing ‘k web’ from the command line.

To summarize my understanding so far:

  • KRE is the current .NET runtime being used.
  • KVM is the utility which manages the KREs for my account, allowing me to upgrade or switch between the active KRE.
  • K is a batch file which needs to be invoked in the folder of the app allowing me to run vNext commands. project.json needs to be available in order for ‘k’ to know what to do. K is relevant to the active KRE.

Conclusions

I see vNext as a major leap and I think MS is on the right path although there’s still a long way to go. I recommend going through the videos specified in the beginning of this blog post, especially the two videos with Scott Hanselman.

In my next post I will plan to discuss vNext and Class Libraries.

 

 
Leave a comment

Posted by on 04/01/2015 in Software Development

 

Tags: , ,