Thursday, May 19, 2016

What is .NET Core and ASP.NET Core

.NET developers are familiar with .NET’s own web development framework which is ASP.NET. The ASP.NET framework supports a magnitude of higher level web development frameworks such as Web Forms, Web  Pages, MVC, Web API, SignalR. The ASP.NET framework was and currently is solid framework for developing modern web applications. However there were a considerable amound of reasons for which Microsoft decided to develop and introduce a new framework termed ASP.NET 5. Few of the key reasons for a new framework are,

  • Open-source the code-base to gain community support and feedback
  • Imporve performance of the traditional ASP.NET runtime
  • Reach out to developers with frequent updates due to competing technologies
  • Enavle cross-platform development/hosting oppertunities
  • Support extensive command-line tooling
  • Introduce simple project structure to quickly and easily create ASP.NET web applications

Introducing of ASP.NET 5

After 2+ years of effort, as of the 18th, November 2015, Microsoft officially released ASP.NET 5. ASP.NET 5 is a brand-new ground-up implementation influenced by the traditional ASP.NET framework. ASP.NET 5 is completely platform agnostic depending on the runtime you decide to use. You are free to utilize the full .NET framework that will enable running on windows only or the .NET Core framework which will enable cross-platform behaviour, and the choise of runtime is completely up to you. Hence the ASP.NET 5 RC1 version was built to run on top of .NET Execution Environment (DNX) and a couple of other supporting tools such as the .NET Version Manager (DNVM) and .NET Development Utilities (DNU). Below are the tasks handled by tools,

DNVM – .NET Version Manager DNVM acts as the version manager that will help you configure what version of the .NET runtime to use, by downloading the required versions of .NET runtime and by setting it at a mechine, process or user level so that your application can pick up the runtime during runtime.

DNX – .NET Execution Environment The DNX is to provide a consistent development and execution environment across multiple operating systems. It is responsible of hosting the CLR by handeling the dependecies and bootstrpping your applicaiton based on the configurations specified in the configuration file that is defined as part of the application.

DNU – .NET Development Utilities As the term suggests, DNU is a tool to support various tasks, such as managing libraries or packaging and publishing your application.

ASP.NET 5 Rebranded to ASP.NET Core

Upon the release of ASP.NET 5 which was an entirely new ground-up implementation, it caused somewhat of a misunderstanding that ASP.NET 5 is a newer version of the current ASP.NET framework and replaces the current version, which was not the case. Hence Micorosoft officially decided to rebranded the term ASP.NET 5 to ASP.NET Core, such that it clears the misunderstanding. This was communicated by Scott Hanselman on 19th, January 2016.

Limitations of ASP.NET Core RC1

ASP.NET 5 was much appriciated by the .NET development comunity. However ASP.NET 5 by design was developed more towards targetting web application development. ASP.NET 5 applications contained Startup.cs class within a class library. The DNX tool runs the ASP.NET hosting library and that would dynamically figure out the Startup.cs class and bootstrap the application.

During this time, Microsoft determined that it was also important to support native/cross-platform console applications. Due to this reason Microsoft had to revamp and introduce a toolchain that will seemlessly be ready for developing of both console and web applications.

With .NET RC2 and ASP.NET RC2 the .NET toolchain is one of the most significant changes that RC2 brings to ASP.NET Core as stated in the Visual Studio blog.

Introducing of ASP.NET Core RC2

As of the 16th, May 2016, Microsoft officially released .NET Core RC2 and ASP.NET Core RC2. The RC2 version of .NET Core and ASP.NET Core addresses the limitations encountered in the RC1 version. As of RC2 an ASP.NET application is bound to behave as a console applicaiton. The console application is responsible of calling on the ASP.NET Hosting libraries as opposed to the other way around that happened in RC1. Although the RC1 way of how things happened are still supported in RC2, RC2’s way provides more visibility and control to the appication developer on determining how the application works.

Going further ASP.NET Core RC2 makes things simpler by relying on a new toolchain called the .NET Command Line Interface (.NET CLI) that comes as part of .NET Core RC2. This tool replaces the old DNVM, DNX and DNU wich was part of the ASP.NET RC1 build. The .NET CLI will perform the tasks that each of the tools in RC1 was responsible, including easy construction, package management, and compilation of applications using the new .NET Core SDK.

Important Details

As confirmed by the Visual Studio blog and Scott Hunter, for the most part of these frameworks runtime/Libraries (CLR, libraries, compilers, etc.) for both .NET Core RC2 and ASP.NET Core RC2 will not change “much” by the time it RTMs which should be available by the end of June. This means we are free to develop go live applications with the RC2 verion of these frameworks .

However the tooling such as the .NET CLI and Visual Studio are still on preview. Microsoft has officially split the delivery of Visual Studio tools from the .NET Core and the ASP.NET Core runtime and libraries. As mentioned by Scott Hunter the tooling supports for .NET CLI and ASP.NET Core are still not at the level of RTM but should be by the end of June.

Summary

The intention of this post is to demystify the understating of .NET Core and ASP.NET Core and provide a breakdown of how related the two are in terms of eveolution of the frameworks. The content of this blog post is a compiled set of information that I have gathered from the various online blogs. I hope this gives you enough information on how ASP.NET is spanning on to reach highrounds and where the framework is heading towards and what how various components interact together. Please do let me know if there is anything I have failed to include or misinterpretted.

Happy Coding!

Thursday, May 12, 2016

Display Loading Indicator with Interceptors in Angular

Most Single Page Applications (SPA) written in Angular, utilize a plethora of asynchronous service calls in the background, some completing instantly and some taking a very long duration just because your ISP provides blazing speeds. Nevertheless, during such situation, it is essential that you display a loading indicator that suggests something like "Loading.." or "Please wait, your connection sucks!".

If your application contains a magnitude of $http service calls that you could hardly remember yourself, modifying each of them to display a loading indicator and hide it before and after each request will kill your time and ultimately you. Just imaging maintaining it! Is there a better way to enable this feature?

I feel your pain, hence this blog is about to detail a mechanism of how you can conveniently incorporate a loading indicator using a custom interceptor that plugs in to the AnguarlJS $httpProvider. To demonstrate this lets create a simple application where upon the user clicking a button we will query a backend service while displaying a loading indicator throughout the period of the HTTP request roundtrip.

Folder Structure

I like segregating an application into specific files and modules merely for maintainability. Before we dive in to the nitty-gritty details, lets observe the Angular application folder structure shown below that I opted to, which by no means are you restricted or limited to,

The pink square depicts the shared module, where I will have shared controllers, services, etc. indexController.js will be a controller that will be used to perform a simple http request. The utilityService.js contains a simple utility function to generate a unique ID and the httpInterceptorService.js will be the interceptor that is used to show/hide the loading indicator for each http request made via Angular.

The red square depicts the application where I have a module.js and rootController.js defined. The module.js at this level is responsible of injecting all the other modules that the application is dependent on (e.g. shared/module.js).

Below is the markup index.html page created as part of this solution, which details the loading of each file and the bootstrapping of the application,

<html>
<head>
    <title>Display Loading Indicator with Interceptors in AngularJS</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
    <script type="text/javascript" src="app/module.js"></script>
    <script type="text/javascript" src="app/rootController.js"></script>
    <script type="text/javascript" src="app/shared/module.js"></script>
    <script type="text/javascript" src="app/shared/services/utilityService.js"></script>
    <script type="text/javascript" src="app/shared/services/httpInterceptorService.js"></script>
    <script type="text/javascript" src="app/shared/controllers/indexController.js"></script>
    <link rel="stylesheet" href="Styles/styles.css" />
</head>
<body ng-app="app" ng-controller="app.RootController">
    <div ng-controller="shared.IndexController">
        <button ng-click="getData()">Get Data</button>
        <div>
            <ul ng-repeat="contact in contacts">
                <li>{{contact}}</li>
            </ul>
        </div>
    </div>
</body>
</html>

Notice the app.RootController at the top most level, and the shared.IndexController at a child level. This will enable the addition of common functionality to the root controller that can be invoked throughout the applications life cycle. Lets see how we could add the show/hide ability of the loading indicator to the root controller below.

Toggling the Loading Indicator

The rootController.js is responsible as functioning as the top-most controller for the entire application and will be the controller the application is bootstraped with, and is typically where its most suitable to add all application wide functionality such as the show/hide functionality of the loading indicator we indent to enable,

angular.module('app')
    .controller('app.RootController', ['$rootScope', function ($rootScope) {

        // Collection to maintain load order.
        var _loadList = {};

        // Display the loading message.
        $rootScope.showLoading = function (id, message) {

            if (_loadList != null && _loadList[id] == null) {
                var data = { id: id, message: message }; 7
                _loadList[id] = data;
            }

            var loadElement = $('div[data-load]');
            if (loadElement.length == 0) {
                $('body').append('<div data-load class="preloader"><img src="http://www.downgraf.com/wp-content/uploads/2014/09/01-progress.gif" /><p data-load-message>' + message + '</p></div>');
            } else {
                loadElement.find('p[data-load-message]').text(message);
            }
        };

        // Hide the loading message.
        $rootScope.hideLoading = function (id) {
            if (_loadList != null && _loadList[id] != null) {
                delete _loadList[id];
            }

            if (Object.keys(_loadList).length != 0) {
                var data = _loadList[Object.keys(_loadList)[Object.keys(_loadList).length - 1]];
                if (data.id != null) {
                    _showLoading(data.id, data.message);
                    return;
                }
            }

            var loadElement = $('div[data-load]');
            loadElement.remove();
        };
    }]);

The code is fairly simple. There are two functions bound to the $rootScope which is showLoading(id, message) and hideLoading(id).  The showLoading(id, message) function is responsible of queuing the message based on the ID and then displaying a animated GIF image that is dynamically added to the DOM using JQuery. The hideLoading(id) function is responsible to removing the ID from the queue and hiding the loading indicator from the DOM. If there are other loading messages queued in the _loadList array, the hideLoading(id) function is responsible of displaying the next immediate loading message.

Having code to show/hide the loading indicator is all good, but we need to enable the mechanism of showing/hiding or invoking the showLoading(id, message)/hideLoading(id) functions accordingly for each $http service request invocation. Lets see on how to enable that using interceptors in Angular next.

Configuring the HTTP Interceptor

We all know what $http in Angular is. The $http is a service in Angular that supports the communication with a backend server via HTTP. Hence in order to add a loading indicator we need the ability to pre/post process each of the requests executed via the $http service. The $httpProvider is how Angular enables this ability, where it contains an array named interceptors. An interceptor in the context of $httpProvider is simply an object that will contain for important methods, which in-fact are request(...), requestError(...), response(...) and responseError(...) that will be triggered for each request made via $http service.

Simple enough! All we need is a mechanism to trigger a way to display a loading message when the request(...) function is triggered and hide the loading message when requestError(...), response(...) and responseError(...) is triggered. Lets see the code of the custom interceptor below,

angular.module('shared')
    .factory('shared.httpInterceptorService', ['$rootScope', '$q', 'shared.utilityService', function ($rootScope, $q, utilityService) {

        // Shows the loading.
        var _showLoading = function (id, message) {
            $rootScope.showLoading(id, message);
        };

        // Hides the loading.
        var _hideLoading = function (id) {
            $rootScope.hideLoading(id);
        };

        return {
            // On request success
            request: function (config) {

                // Inject unique ID to config and and show loading. Show loading only if backgroundLoad property is not set or set to false.
                if (config != null) {
                    config.id = utilityService.scriptHelper.getUniqueId();
                    _showLoading(config.id, config.loadMessage != null ? config.loadMessage : 'Loading...');
                }

                // Return the config or wrap it in a promise if blank.
                return $q.when(config);
            },

            // On request failure
            requestError: function (rejection) {

                // Hide loading triggered against the unique ID.
                if (rejection != null && rejection.config != null) {
                    _hideLoading(rejection.config.id);
                }

                // Return the promise rejection.
                return $q.reject(rejection);
            },

            // On response success
            response: function (response) {

                // Get unique id from config and hide loading. Hide loading only if backgroundLoad property is not set or set to false.
                var config = response.config;
                if (config != null) {
                    _hideLoading(config.id);
                }

                // Return the response or promise.
                return $q.when(response);
            },

            // On response failure
            responseError: function (rejection) {

                // Hide loading triggered against the unique ID.
                if (rejection != null && rejection.config != null) {
                    _hideLoading(rejection.config.id);
                }

                // Return the promise rejection.
                return $q.reject(rejection);
            }
        };
    }]);

There are a couple of things going on here. First off, lets understand the four important methods of the interceptor,

  • request(...) function: This function is called before the request is sent over to the backend. The function is passed with a configuration object and you are free to modify the config object as required and this config object will be passed to each of the other three functions. Likewise I am adding a unique ID generated via the utilityService.js to the config object, which will then be passed to the _showLoading(id, message) function and get queued. You are further required to return a valid configuration or promise or the request will be terminated/rejected.

  • response(...) function: This function is called as soon as a response is received from the backend. As of this point we retrieve the unique ID from the config object and call the _hideLoading(id) function. You are further required to return a valid configuration or promise or the request will be terminated/rejected.

  • requestError(...) function: The current interceptor is not the only interceptor, and there can be interceptors chained together. During certain situations a request can fail due to other interceptors throwing errors, or for other network or backend related issues. in this case as well we retrieve the unique ID from the config object and call the _hideLoading(id) function. You are further required to return a valid configuration or promise or the request will be terminated/rejected.

  • responseError(...) function: At certain tims there are situations where interceptors in the chan fail, or there can be situation where the backend failed to provide a successful response. In either case we retrieve the unique ID from the config object and call the _hideLoading(id) function. You are further required to return a valid configuration or promise or the request will be terminated/rejected.

You may have noticed the term promise quite a few times. Promise is a JS based pattern for differed execution/asynchronous programming. Please refer the $q documentation to gain more understanding on the promises in the context of Angular.

Summary

Provided all goes well, you should see and output similar to the following for each $http invocation in you application,

Provide you are unable to get things working, download the sample application from below and try it out.

Happy Coding!

About Me

I am a software developer with over 7+ years of experience, particularly interested in distributed enterprise application development where my focus is on development with the usage of .Net, Java and any other technology that fascinate me.