Chitika

November 14, 2012

JavaScript modularity with RequireJS (from spaghetti code to ravioli code)

Today I would like to describe how you can make your JavaScript code much much much better.

We know a lot about how to make our c# code much better. And we always use it.
We split out our c# code to classes, put the classes to modules, put the modules to layers, etc.

But we never do the same for our JavaScript code. And this is a big mistake.

And that's why we have a lot of Spaghetti Code inside our apps.

The main problems with function spaghetti code are:

  • It's really hard to figure out where the one block of code begins and where the other ends
  • Who's responsible for what?
  • How are we deal with global scope pollution (e.g. use the same variables in different pieces of code)
  • Low code re-use
  • Not easy to maintain, test and debug.

I'm not going to describe in details what the functional spaghetti code is, because you can find a lot of references in the Internet.
I would like to show here how to avoid it and make your code better using RequireJS.

Function spaghetti code

Let's start with a simple example of spaghetti code. (I can't say that it is really good example of horrible spaghetti code, but it is simple, so it's easy to understand and see all the changes)

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Phase 1</title>
</head>
<body>
    <div>
        <h1>Modular Demo 1</h1>
    </div>
    <div id="messagebox"></div>

    <script src="../Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>

    <script type="text/javascript">

        var baseUrl = '/api/messenger/';

        function ShowMessage(id) {
            $.ajax({
                url: baseUrl + id,
                type: 'GET',
                dataType: 'json',
                success: function(data) {
                    $("#messagebox").html(data);
                }
            });
        }

        var id = 55;
        ShowMessage(id);
        
    </script>
</body>
</html>

As you can see it's really simple example. The code sends ajax request to get a message from server and then puts this message to div container.
This code is correct and works well. And at the same time not perfect but is an example of spaghetti code.

All of your code logic (sending the request, putting a message to a div container) located in the same function.

I would like to repeat again, that it is not perfect example, but we need really simple one to better undersand how we can improve it.

JavaScript modules

First of all I would like to describe how you can use the module pattern to create a module in JavaScript.

Let's start with an example first.

        var messenger = (function ($) {
            var text = 'I am a module',
                showMessage = function() {
                    $("#messagebox").html(text);
                };

            return {
                showMessage: showMessage
            };
        })($);

That's it. You have a module - messenger.
This module has internal part:

            text = 'I am a module',

And exposes externally function:

            return {
                showMessage: showMessage
            };

So, for the other code only showMessage will be visible.
And it is really simple to use it:

            messenger.showMessage();

Also in this example our module depends on jQuery. You can see it here:

        var messenger = (function ($) {
            . . .
        })($);

As you can see it's really simple to create a module in JavaScript.

Let's see how we can re-factor our code.

Ravioli code

When you eating the ravioli you are totally sure where is the one ravioli and where is another one.
Also, to take SRP (single responsibility principle) into account we have to separate our code into modules which have only single responsibilities.

This is the result:

        var config = (function() {
            var baseUrl = '/api/messenger/';

            return {
                baseUrl: baseUrl
            };
        })();

        var dataservice = (function($, config) {
            var callApi = function (url, type, callback) {
                    $.ajax({
                        url: url,
                        type: type,
                        dataType: 'json',
                        success: function (data) {
                            callback(data);
                        }
                    });
                },
                getMessage = function (id, callback) {
                    url = config.baseUrl + id;
                    callApi(url, 'GET', callback);
                };

            return {
                getMessage: getMessage
            };
        })($, config);

        var messenger = (function ($, dataservice) {
            var showMessage = function(id) {
                dataservice.getMessage(id, function(message) {
                    $("#messagebox").html(message);
                });
            };

            return {
                showMessage: showMessage
            };
        })($, dataservice);

        (function (messenger) {
            var id = 55;
            messenger.showMessage(id);
        })(messenger);

As a result we have 4 modules. Let's describe them:

  • config module - for storing our global variables
  • dataservice module - for doing communication with the server (sending ajax requests and getting the response back)
  • messenger module - for showing a message (placing a message into containers)
  • main module - as starting point of our app

And it's really easy now to change our modules if needed, for example if we will decide to change our communication mechanism with the server, or to change our messenger to show a message into jQuery dialog.

Split out your modules

The next step is splitting your modules out into JavaScript files.
Because it is not really good solution to place your JavaScript code into HTML.

At the end you will have four JavaScript files.

config.js

        var config = (function() {
            var baseUrl = '/api/messenger/';

            return {
                baseUrl: baseUrl
            };
        })();

dataservice.js

        var dataservice = (function($, config) {
            var callApi = function (url, type, callback) {
                    $.ajax({
                        url: url,
                        type: type,
                        dataType: 'json',
                        success: function (data) {
                            callback(data);
                        }
                    });
                },
                getMessage = function (id, callback) {
                    url = config.baseUrl + id;
                    callApi(url, 'GET', callback);
                };

            return {
                getMessage: getMessage
            };
        })($, config);   

messenger.js

        var messenger = (function ($, dataservice) {
            var showMessage = function(id) {
                dataservice.getMessage(id, function(message) {
                    $("#messagebox").html(message);
                });
            };

            return {
                showMessage: showMessage
            };
        })($, dataservice);

main.js

        (function (messenger) {
            var id = 55;
            messenger.showMessage(id);
        })(messenger);

Also, we have to change our HTML to load all of these JavaScript files.

index.html

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Phase 1</title>
</head>
<body>
    <div>
        <h1>Modular Demo 1</h1>
    </div>
    <div id="messagebox"></div>

    <script src="../Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>

    <script src="config.js" type="text/javascript"></script>
    <script src="dataservice.js" type="text/javascript"></script>
    <script src="messenger.js" type="text/javascript"></script>
    <script src="main.js" type="text/javascript"></script>
   
</body>
</html>

Finally, our code looks much better now.

Loading modules in proper order

Everything almost perfect in our code, except of loading scripts in the proper order.
Honestly, we do this task, but we do it manually.
Everything changes if you decide to order your modules in HTML files in alphabetical order.

    <script src="config.js" type="text/javascript"></script>
    <script src="dataservice.js" type="text/javascript"></script>
    <script src="main.js" type="text/javascript"></script>
    <script src="messenger.js" type="text/javascript"></script>

I've just put the module main.js above messenger.js. And unfortunately it has really changed behavior of our app.
Instead of showing a message it shows an exception now.

Line: 1
Error: 'messenger' is undefined

It has been happened because we changed the order, and module main.js has been loaded before messenger.js. As a result module main.js tries to call messenger.showMessage(), but the messenger is undefined, because it has not been loaded yet.

Of course, in this simple example we can easily control the order of the four scripts, but in a real application we can manage 30, or 50 or even more modules.

And it becomes a serious problem.

In this case RequireJS can really helps.

RequireJS

The following command in the Package Manager console will install RequireJS package into your ASP.NET application:

PM > Install-Package RequireJS

RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.

In other words RequireJS really helps:

  • To define our modules
  • To resolve module dependencies
  • To load scripts in the proper order (and asynchronously)

So, RequireJS really helps to define a structure to the modules in a JavaScript applications.

RequireJS modules

First I would like to show how you can create modules using RequireJS.
I will use the same example as I used to show how to create a JavaScript module.

    define('messenger',
        ['jquery'],
        function ($) {
            var text = 'I am a module',
                showMessage = function() {
                    $("#messagebox").html(text);
                };

            return {
                showMessage: showMessage
            };
        }
    );

It looks as easy as a JavaScript module. But I would like to describe some differences.
The RequireJS module starts with:

    define('messenger',

Where 'messenger' is the module ID. You can use this ID if you want to reference this module in other modules.

The next line describes dependencies of this module:

       ['jquery'],

In this example our module depends on jQuery only.

And then you have to specify module body as a function.

As you can see it's really simple to create a module using RequireJS.

Using RequireJS

Let's change all of our modules.

config.js

define('config',
    [],
    function () {
        var baseUrl = '/api/messenger/';

        return {
            baseUrl: baseUrl
        };
    }
);

dataservice.js

define('dataservice',
    ['jquery', 'config'],
    function ($, config) {
        var
            callApi = function (url, type, callback) {
                $.ajax({
                    url: url,
                    type: type,
                    dataType: 'json',
                    success: function (data) {
                        callback(data);
                    }
                });
            },
            
            getMessage = function (id, callback) {
                url = config.baseUrl + id;
                callApi(url, 'GET', callback);
            };

        return {
            getMessage: getMessage
        };
    }
);

messenger.js

define('messenger',
    ['jquery', 'dataservice'],
    function ($, dataservice) {
        var showMessage = function (id) {
            dataservice.getMessage(id, function (message) {
                $("#messagebox").html(message);
            });
        };

        return {
            showMessage: showMessage
        };
    }
);

main.js

(function() {
    requirejs.config(
        {
            paths: {
                'jquery': '../Scripts/jquery-1.8.2.min'
            }
        }
    );

    require(
        ['messenger'],
        function(messenger) {
            var id = 55;
            messenger.showMessage(id);
        }
    );
})();

All of the modules look as they were before, except of main module.

In this module I have configured RequireJS to specify where RequiteJS can find the jquery module.

    requirejs.config(
        {
            paths: {
                'jquery': '../Scripts/jquery-1.8.2.min'
            }
        }
    );

And then, I've specified the start up code, which depends on messenger module:

    require(
        ['messenger'],
        function(messenger) {
            var id = 55;
            messenger.showMessage(id);
        }
    );

After all, we have to change our HTML to load our modules.

index.html

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Phase 1</title>
</head>
<body>
    <div>
        <h1>Modular Demo 1</h1>
    </div>
    <div id="messagebox"></div>

    <script data-main="main" src="../Scripts/require.js" type="text/javascript"></script>
   
</body>
</html>

Small remarks about our HTML changes.

We should not load any of our modules or jQuery, because RequireJS will handle it for us.
We have to load RequireJS only, and specify 'data-main' attribute, which tells RequireJS to load main.js script after RequireJS loads. In other words, we specify start up script in 'data-main' attribute.

And after all RequireJS does the 'magic' and loads all of our modules in proper order automatically.

As a result, our code becomes much much better now, as I promised at the beginning of this post.

That's all. And see you next time.

June 27, 2012

ASP.NET MVC 4 WebAPI. Support Areas in HttpControllerSelector

This article was written for ASP.NET MVC 4 RC (Release Candidate). If you are still using Beta version of ASP.NET MVC 4 then you have to read the previous article.

HttpControllerFactory was deleted in ASP.NET MVC 4 RC. Actually, it was replaced by two interfaces: IHtttpControllerActivator and IHttpControllerSelector.

Unfortunately DefaultHttpControllerSelector still doesn't support Areas by default. To support it you have to write your HttpControllerSelector from scratch. To be honest, I will derive my selector from DefaultHttpControllerSelector.

In this post I will show you how you can do it.

AreaHttpControllerSelector

First of all, you have to derive your class from DefaultHttpControllerSelector class:

    public class AreaHttpControllerSelector : DefaultHttpControllerSelector
    {
        private readonly HttpConfiguration _configuration;

        public AreaHttpControllerSelector(HttpConfiguration configuration)
            : base(configuration)
        {
            _configuration = configuration;
        }
    }

In the constructor mentioned above I called the base constructor and stored the HttpConfiguration. We will use it a little bit later.

My code will use two constants:

        private const string ControllerSuffix = "Controller";
        private const string AreaRouteVariableName = "area";

You can understand why we need first one by name. The second one contains the name of the variable which we will use to specify area name in Routes collection.

Somewhere we have to store all of the API controllers.

        private Dictionary<string, Type> _apiControllerTypes;

        private Dictionary<string, Type> ApiControllerTypes
        {
            get { return _apiControllerTypes ?? (_apiControllerTypes = GetControllerTypes()); }
        }

        private static Dictionary<string, Type> GetControllerTypes()
        {
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();

            var types = assemblies.SelectMany(a => a.GetTypes().Where(t => !t.IsAbstract && t.Name.EndsWith(ControllerSuffix) && typeof(IHttpController).IsAssignableFrom(t)))
                .ToDictionary(t => t.FullName, t => t);

            return types;
        }

Method GetControllerTypes takes all the API controllers types from all of your assemblies, and store it inside the dictionary, where the key is FullName of the type and value is the type itself.
Of course we will set this dictionary only once. And then just use it.

Now we are ready to implement one of the important method:

        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            return GetApiController(request) ?? base.SelectController(request);
        }

In that method I try to take the HttpControllerDescriptor from method GetApiController and if it return null then call the base method.

And additional methods:

        private static string GetAreaName(HttpRequestMessage request)
        {
            var data = request.GetRouteData();

            if (!data.Values.ContainsKey(AreaRouteVariableName))
            {
                return null;
            }

            return data.Values[AreaRouteVariableName].ToString().ToLower();
        }

        private Type GetControllerTypeByArea(string areaName, string controllerName)
        {
            var areaNameToFind = string.Format(".{0}.", areaName.ToLower());
            var controllerNameToFind = string.Format(".{0}{1}", controllerName, ControllerSuffix);

            return ApiControllerTypes.Where(t => t.Key.ToLower().Contains(areaNameToFind) && t.Key.EndsWith(controllerNameToFind, StringComparison.OrdinalIgnoreCase))
                    .Select(t => t.Value).FirstOrDefault();
        }

        private HttpControllerDescriptor GetApiController(HttpRequestMessage request)
        {
            var controllerName = base.GetControllerName(request);

            var areaName = GetAreaName(request);
            if (string.IsNullOrEmpty(areaName))
            {
                return null;
            }

            var type = GetControllerTypeByArea(areaName, controllerName);
            if (type == null)
            {
                return null;
            }

            return new HttpControllerDescriptor(_configuration, controllerName, type);
        }
Method GetAreaName just takes area name from HttpRequestMessage.

Method GetControllerTypeByArea are tries to find the controller in the ApiControllerTypes by full name of the controller where the full name contains area's name surrounded by "." (e.g. ".Admin.") and ends with controller name + controller suffix (e.g. UsersController).

And if a controller type found then method GetApiController will create and return back HttpControllerDescriptor.

So, my AreaHttpControllerSelector is ready to be registered in my application.

Registering AreaHttpControllerSelector

The next thing you have to do is to say to your application to use this controller selector instead of DefaultHttpControllerSelector. And fortunately it is really easy - just add one additional line to the end of Application_Start method in Glogal.asax file:
        protected void Application_Start()
        {
            // your default code
                    GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new AreaHttpControllerSelector(GlobalConfiguration.Configuration));
        }
That's all.

Using AreaHttpControllerSelector

If you did everything right, now you can forget about that "nightmare" code mentioned above. And just start to use it!

You have to add new HttpRoute to your AreaRegistration.cs file:

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.Routes.MapHttpRoute(
                name: "Admin_Api",
                routeTemplate: "api/admin/{controller}/{id}",
                defaults: new { area = "admin", id = RouteParameter.Optional }
            );

            // other mappings
        }

Or just use one global route in your Global.asax like:


            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{area}/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

That's all. Good luck, and have a nice day.

April 23, 2012

Localizable text template engine using StringTemplate 4

In the previous post I shown how to create localizable text template engine using RazorEngine.
I suggest to use the RazorEngine in any case.
But there is an one case where RazorEngine can not help you. It will happened if you try to use RazorEngine in dynamically loaded assembly.
There is a simple example. Your system can load the plugins dynamically. One of your plugin have to use text template engine to parse the strings. In that case RazorEngine will throw an error with the message:

Precondition failed: templateType != null

It's known issue and if you interested in it you can find a detailed description of this problem here.

In that case, you have to use something else for a template engine and I suggest to use StringTemplate to avoid that kind of problems.

In this post I will show you how to use StringTemplate engine.


Using the StringTemplate engine


The following command in the Package Manager console will install StringTemplate 4 package into your ASP.NET MVC 4 WebAPI application:

PM > Install-Package Antlr4.StringTemplate

StringTemplate is a template engine library used for generating text from data structures. StringTemplate's distinguishing characteristic is that it strictly enforces model-view separation unlike other comparable template engines. It is particularly good at multi-targeted code generators, multiple site skins, and internationalization/localization.

So, it fully meets our needs.

In my previous post I shown how to write and use the localizable template service.

So, here I will talk only about another realization of the interface ITemplateEngine for StringTemplate, because everything else will stay the same.

I would like to remind you how the ITemplateEngine interface looks:

    public interface ITemplateEngine
    {
        string Parse(string template, dynamic model);
    }

And there is the realization of this interface for StringTemplate engine:

    public class StringTemplateEngine : ITemplateEngine
    {
        public string Parse(string template, dynamic model)
        {
            var group = new TemplateGroupString("group", "delimiters \"$\", \"$\"");

            var renderer = new AdvancedRenderer();
            group.RegisterRenderer(typeof(DateTime), renderer);
            group.RegisterRenderer(typeof(double), renderer);

            group.DefineTemplate("template", template, new[] { "Model" });

            var stringTemplate = group.GetInstanceOf("template");
            stringTemplate.Add("Model", model);

            return stringTemplate.Render();
        }
    }

It is a little bit complicated example and I will explain you why.
The first line just creates a template group with specified delimiters '$' (default delimiters are '<' and '>').
The next three lines help us to specify the renderer for the types DateTime and double. I have to use custom renderer to allow formatting my DateTime and double values, and that is only one reason why I use the template group instead of specify only one template.
The next line creates new template in the template group with the name 'template' and use the template text for a content of the template.
Then I take this template from a group and add my model to template.
At last, just call Render method of the template and return result back.

To make formatting inside the template possible I use custom renderer for StringTemplate called AdvancedRenderer:

    public class AdvancedRenderer : IAttributeRenderer
    {
        public string ToString(object obj, string formatString, System.Globalization.CultureInfo culture)
        {
            if (obj == null)
                return null;

            if (string.IsNullOrEmpty(formatString))
                return obj.ToString();

            return string.Format("{0:" + formatString + "}", obj);
        }
    }

It is really simple but powerful renderer. I will show you how to use the formatting directly in the template later.

So, I have done with the template engine. And we can start using it already.

In the last part of the post, I would like to share the example of template that would be easier to understand the syntax of StringTemplate.

Using the localizable template service


To demonstrate how to use this service let's create the template file first.
Create a directory 'Templates' in your project.
Then click the right mouse button on this directory in the 'Solution Explorer' and select 'Add' -> 'New Item...' (or just press Ctrl+Shift+A).
In the new window click on 'Visual C# Items' and select the 'Text File' in the list. Enter the file name - 'first.template' and click 'Add' button.

Then insert the next text into template file:

ID: $Model.Id$
CreatedDate: $Model.CreatedDate; format="dd.MM.yyyy HH:mm"$
Name: $Model.Name$
Price: $Model.Price; format="0.00"$
Items:
$Model.Items:{item |
    item $i$ - $item.Key$  $if(item.Value)$enabled$else$-$endif$
}$

Then write some simple code to prepare the data model and to parse the template:

            
            var model = new { 
                Id = 10,
                CreatedDate = DateTime.Now,
                Name = "Name1",
                Price = 123.45356,
                Items = new List<KeyValuePair<string, bool>> {
                    new KeyValuePair<string, bool>("Item1", false),
                    new KeyValuePair<string, bool>("Item2", true),
                    new KeyValuePair<string, bool>("Item3", false),
                    new KeyValuePair<string, bool>("Item4", false),
                    new KeyValuePair<string, bool>("Item5", true)
                }
            };

            var templateService = new TemplatesService(new FileSystemService(), new StringTemplateEngine());

            var result = templateService.Parse("first", model);

You can find detailed information about TemplateService and FileSystemService in my previous post how to create localizable text template engine using RazorEngine.

After that, put the break point after the last line (var result = ...) and run your application in Debug mode.
When the debugger stops on that break point just check the value of the result variable in the Text Visualizer.

If should contains the next text:

ID: 10
CreatedDate: 23.04.2012 15:54
Name: Name1
Price: 123.45
Items:
    item 1 - Item1  -
    item 2 - Item2  enabled
    item 3 - Item3  -
    item 4 - Item4  -
    item 5 - Item5  enabled

So, as you can see our renderer (AdvancedRenderer) allows us to specify string for formatting as we use usually for string.Format() method.

That's all.
Good luck.

April 19, 2012

Localizable text template engine using RazorEngine

In some cases you need to use something like text template engine in your applications.
The best example is sending the email messages from an application.
Of course you can write a subject and a body for email message directly in your code:

    var subject = string.Format("Details about item ID - {0}", item.Id);
    var body = string.Format(@"Dear {0} {1},
This is a details about your item ID - {2}.
Regards.", item.FirstName, item.LastName, item.Id);

And everything is OK unless somebody ask you to change the text of  a subject or a body message.
In that case you have to change it in the code, release your application and deploy it again.
It often happens that when you already finished the deployment, you receive the new text message for a body, and based on my experience you will receive that kind of messages again and again.
Then somebody can ask you - what about localization? You need to send one message in English and another message in German. Later somebody ask about a Korean message, etc.

So, it's good example where a text template engine could help you.

In this post i will show you how to use RazorEngine for it.


Using the RazorEngine


The following command in the Package Manager console will install RazorEngine package into your ASP.NET MVC 4 WebAPI application.

PM > Install-Package RazorEngine

RazorEngine is a templating engine built upon Microsoft's Razor parsing technology. The RazorEngine allows you to use Razor syntax to build robust templates. Currently RazorEngine has integrated the vanilla Html + Code support, but it would support other markup languages in future.

So, let's start with TemplateEngine interface:

    public interface ITemplateEngine
    {
        string Parse(string template, dynamic model);
    }

This interface introduce just one method which receive a template text and a data model for a template in a parameters and send the generated text back.

Continue with realization:

    public class RazorTemplateEngine : ITemplateEngine
    {
        public string Parse(string template, dynamic model)
        {
            return Razor.Parse(template, model);
        }
    }

It's really easy, just don't forget include RazorEngine to your using block.


The localized templates service


Our template engine is ready. But we don't want to just convert one text to another using string variables.
We would like to specify the template name, the template data model and the current culture, and get the generated text back.

For that reason I will create an TemplatesService class, but let's start with an interface first:

    public interface ITemplatesService
    {
        string Parse(string templateName, dynamic model, CultureInfo cultureInfo = null);
    }

This simple interface has only one method which takes the template name, data model and current culture as a parameters and will return the generated text as well.

Realization of this simple interface is not so simple, but i will explain all the methods later.
But before I show you the realization I would like to tell you that our TemplatesService class needs to do some file system operations, e.g. read all contents of the files, check if a file exists.

I suggest to create a separate interface (and realization of course) to do all of this file system tasks. It allows you to avoid a lot of problems in unit testing, and make your services more clear to another developers.

The interface for the file system operations:

    public interface IFileSystemService
    {
        string ReadAllText(string fileName);
        bool FileExists(string fileName);
        string GetCurrentDirectory();
    }

And really simple realization:

    public class FileSystemService : IFileSystemService
    {
        public string ReadAllText(string fileName)
        {
            return File.ReadAllText(fileName);
        }

        public bool FileExists(string fileName)
        {
            return File.Exists(fileName);
        }

        public string GetCurrentDirectory()
        {
            return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        }
    }

I hope everything is clear to you in this class.

So, let's return to realization of TemplatesService. I will show you the realization from methods to methods. The constants, the properties and a constructor of the class, first:

    public class TemplatesService : ITemplatesService
    {
        private const string DefaultLanguage = "en";
        private const string TemplatesDirectoryName = "Templates";
        private const string TemplateFileNameWithCultureTemplate = "{0}.{1}.template";
        private const string TemplateFileNameWithoutCultureTemplate = "{0}.template";
        
        private readonly IFileSystemService _fileSystemService;
        private readonly ITemplateEngine _templateEngine;
        private readonly string _templatesDirectoryFullName;

        public TemplatesService(IFileSystemService fileSystemService, ITemplateEngine templateEngine)
        {
            _fileSystemService = fileSystemService;
            _templateEngine = templateEngine;
            _templatesDirectoryFullName = Path.Combine(_fileSystemService.GetCurrentDirectory(), TemplatesDirectoryName);
        }

        // rest of the code
    }

Nothing complex in this code: just declaring the four constants where I specified the default language name, the name of the directory where the templates are stored, and the string templates for the file name of template with and without a culture.
Also, I stored the full path to templates directory in the _templateDirectoryFullName property in the constructor of the class.

Then, the implementation of the one public method which declared in the interface:

        public string Parse(string templateName, dynamic model, CultureInfo cultureInfo = null)
        {
            var templateContent = GetContent(templateName, cultureInfo);

            return _templateEngine.Parse(templateContent, model);
        }

It takes the content of the template from GetContent method and call the template engine to get a string result.

        private string GetContent(string templateName, CultureInfo cultureInfo)
        {
            var templateFileName = TryGetFileName(templateName, cultureInfo);
            if (string.IsNullOrEmpty(templateFileName))
            {
                throw new FileNotFoundException(string.Format("Template file not found for template '{0}' in '{1}'", templateName, _templatesDirectoryFullName));
            }

            return _fileSystemService.ReadAllText(templateFileName);
        }

Te method GetContent tries to take the template full file name (a file name with a path) from the method TryGetFileName, and if this method return null or empty string throws an exception. Otherwise it reads all the template file content and return it.

        private string TryGetFileName(string templateName, CultureInfo cultureInfo)
        {
            var language = GetLanguageName(cultureInfo);

            // check file for current culture
            var fullFileName = GetFullFileName(templateName, language);
            if (_fileSystemService.FileExists(fullFileName))
            {
                return fullFileName;
            }

            // check file for default culture
            if (language != DefaultLanguage) 
            {
                fullFileName = GetFullFileName(templateName, DefaultLanguage);
                if (_fileSystemService.FileExists(fullFileName))
                {
                    return fullFileName;
                }
            }

            // check file without culture
            fullFileName = GetFullFileName(templateName, string.Empty);
            if (_fileSystemService.FileExists(fullFileName))
            {
                return fullFileName;
            }

            return string.Empty;
        }

This method gets the language name from CultureInfo parameters, and checks is the template file for that language exist, and if no, checks is the template file for default language exists, and if it is not found then checks is the template file without any culture exist.
For example, look at the templates files structure:

    subject.template
    subject.de.template

Let's imagine, that the current culture is German. The language is "de". The method should check the template file for this language and should found the second template 'subject.de.template'.
Then, let's imagine, that for now, the current culture is Korean. The language is "ko". The method should check the template file for this language, and will not find it, because we don't have a template file for Korean culture. Then the method should check the template file for default language which is 'en', and will not find it as well. The latest check will be for the template file without any culture and the first one template 'subject.template' should be found.

The implementation of the GetLanguage method is really simple:

        private static string GetLanguageName(CultureInfo cultureInfo)
        {
            return cultureInfo != null ? cultureInfo.TwoLetterISOLanguageName.ToLower() : DefaultLanguage;
        }

It returns the two letter ISO language name or the default language name if culture is not specified.

And the last method:

        
        private string GetFullFileName(string templateName, string language)
        {
            var fileNameTemplate = string.IsNullOrEmpty(language) ? TemplateFileNameWithoutCultureTemplate : TemplateFileNameWithCultureTemplate;

            var templateFileName = string.Format(fileNameTemplate, templateName, language);

            return Path.Combine(_templatesDirectoryFullName, templateFileName);
        }

That's all with the TemplatesService.


Using the localizable template service


To demonstrate how to use this service let's create the template file first.
Create a directory 'Templates' in your project.
Then click the right mouse button on this directory in the 'Solution Explorer' and select 'Add' -> 'New Item...' (or just press Ctrl+Shift+A).
In the new window click on 'Visual C# Items' and select the 'Text File' in the list. Enter the file name - 'first.template' and click 'Add' button.

Then insert the next text into template file:

ID: @Model.Id
Name: @Model.Name
Items:
@for(int i = 0; i < @Model.Items.Count; i++) {
    @:item #@i - @Model.Items[i]
}

Then write some simple code to parse the template:

            var model = new {
                Id = 10,
                Name = "Name1",
                Items = new List<string> {"Item1", "Item2", "Item3", "Item4", "Item5"}
            };

            var templateService = new TemplatesService(new FileSystemService(), new RazorTemplateEngine());

            var result = templateService.Parse("first", model);

After that, put the break point after the last line (var result = ...) and run your application in Debug mode.
When the debugger stops on that break point just check the value of the result variable in the Text Visualizer.

If should contains the next text:

ID: 10
Name: Name1
Items:
    item #0 - Item1
    item #1 - Item2
    item #2 - Item3
    item #3 - Item4
    item #4 - Item5

In my next post you can find how to create a localizable text template engine using StringTemplate.

That's all.
Good luck.

April 6, 2012

Dependency Injection in ASP.NET MVC 4 and WebAPI using Unity

In this post, I will demonstrate how to use Dependency Injection in ASP.NET MVC 4 application and WebAPI using Unity. The new ASP.NET MVC 4 is a great framework for building web applications and WebAPI is a great for building HTTP services. I will use Unity IoC container to provide the integration with ASP.NET MVC 4 and WebAPI for applying dependency injection.

Using Unity in ASP.NET MVC 4


The following command in the Package Manager console will install Unity.Mvc3 package into your ASP.NET MVC 4 WebAPI application.

PM > Install-Package Unity.Mvc3

Unity.Mvc3 is a package that allows simple Integration of Microsoft's Unity IoC container with ASP.NET MVC 3. It also works great for ASP.NET MVC 4.

After installation of the package you will find the Bootstrapper.cs file in the root of your ASP.NET MVC 4 WebAPI project. The course code of that file is:

    public static class Bootstrapper
    {
        public static void Initialise()
        {
            var container = BuildUnityContainer();

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }

        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // e.g. container.RegisterType<itestservice, testservice="">();            

            return container;
        }
    }

We will return to this class a little bit later.

To get started, we should add a call to Bootstrapper.Initialize() in the end of the Application_Start method of Global.asax.cs and the MVC framework will then use the Unity.Mvc3 DependencyResolver to resolve your components.

        protected void Application_Start()
        {
            // Default code of the method
            // . . .

            // Initialization of our Unity container
            Bootstrapper.Initialise();
        }


Using Unity in ASP.NET MVC 4 WebAPI


Unfortunately Unity.Mvc3 doesn't change the DependencyResolver for WebAPI. I hope it will be implemented in Unity.Mvc4.
However, there is the nuget package that has already implemented needed functionality - Unity.WebAPI.

The following command in the Package Manager console will install Unity.WebAPI package into your ASP.NET MVC 4 WebAPI application.

PM > Install-Package Unity.WebAPI

Unity.WebAPI is a library that allows simple Integration of Microsoft's Unity IoC container with ASP.NET's WebAPI. This project includes a bespoke DependencyResolver that creates a child container per HTTP request and disposes of all registered IDisposable instances at the end of the request.

After installation of the package you just have to add one line of code to your Bootstrapper class into the Initialise method:

        public static void Initialise()
        {
            var container = BuildUnityContainer();

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            // register dependency resolver for WebAPI RC
            GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
            // if you still use the beta version - change above line to:
            //GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new Unity.WebApi.UnityDependencyResolver(container));
        }

After that you are ready to create your business logic.

Create service


Let's start with the service class that we want to use in our containers.

First, we will create the interface:

    public interface IValuesService
    {
        int Create(string value);
        string Update(int id, string value);
        void Delete(int id);

        IDictionary<int, string> GetAll();
        string Get(int id);
    }

And the service class which contains realization of this interface:

    public class ValuesService : IValuesService
    {
        private Dictionary<int, string> _values;

        public ValuesService()
        {
            _values = new Dictionary<int, string>
                          {
                              {1, "Value 1"},
                              {2, "Value 2"},
                              {3, "Value 3"},
                              {4, "Value 4"},
                              {5, "Value 5"},
                          };
        }

        private int GetNextId()
        {
            return _values.Keys.Max() + 1;
        }

        public int Create(string value)
        {
            var id = GetNextId();
            _values.Add(id, value);
            return id;
        }

        public string Update(int id, string value)
        {
            _values[id] = value;
            return Get(id);
        }

        public void Delete(int id)
        {
            _values.Remove(id);
        }

        public IDictionary<int, string> GetAll()
        {
            return _values;
        }

        public string Get(int id)
        {
            return _values[id];
        }
    }


This is the really simple service with some predefined values in the constructor (just for this simple example). Of course in the real life your services will be much more complex.

Register service


The next step is register our service and interface in Unity container. This is very simple, you just have to add one line of code to the Bootstrapper class into the BuildUnityContainer method:

        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            // register values service
            container.RegisterType<IValuesService, ValuesService>();

            return container;
        }

As you can see it is really simple.
Also, if you read this method carefully you should see that Unity.Mvc3 registered all of our controllers by default in the Unity container. This is the line where it's happened:

            container.RegisterControllers();


Inject service to Controller


So, let's get our service in the home controller:

    public class HomeController : Controller
    {
        private readonly IValuesService _valuesService;

        public HomeController(IValuesService valuesService)
        {
            _valuesService = valuesService;
        }

        public ActionResult Values()
        {
            var viewModel = _valuesService.GetAll();

            return View(viewModel);
        }


        // old code
        public ActionResult Index()
        {
            return View();
        }
    }

I've just added the constructor which receive IValuesService as a parameters. And Unity will do all the "magic" of resolving out service interface for us.
Then. to test it, let's create a simple view named as the same as the action - Values.cshtml (tip: you can create a view just clicking the right mouse button on the action name, and selecting 'Add View...' in the context menu):

@model Dictionary<int,string>

@{
    ViewBag.Title = "Values";
}

<h2>Values</h2>

<ul>
    @foreach(var item in Model)
    {
        <li>ID: @item.Key, Value: @item.Value</li>
    }
</ul>

Then, compile our solution and run it.
Then, navigate to http://localhost:<your port number>/Home/Values. You should see the list of the five values with ID.
If you see it then injection for our Controllers works properly.

Inject service to ApiController


Next, let's inject our service to ApiControllers:

    public class ValuesController : ApiController
    {
        private readonly IValuesService _valuesService;
        
        public ValuesController(IValuesService valuesService)
        {
            _valuesService = valuesService;
        }

        // GET /api/values
        public IEnumerable<KeyValuePair<int, string>> Get()
        {
            return _valuesService.GetAll();
        }

        // GET /api/values/5
        public string Get(int id)
        {
            return _valuesService.Get(id);
        }

        // POST /api/values
        public void Post(string value)
        {
            _valuesService.Create(value);
        }

        // PUT /api/values/5
        public void Put(int id, string value)
        {
            _valuesService.Update(id, value);
        }

        // DELETE /api/values/5
        public void Delete(int id)
        {
            _valuesService.Delete(id);
        }
    }

To test is everything fine with the ApiController, just compile the solution and run it.
After that, open the IE developers tools and click the 'Start capturing' button in the Network tab.
Then, navigate to http://localhost:<your port number>/api/values.
You should see something like this in the Response body tab:

[{"key":1,"value":"Value 1"},{"key":2,"value":"Value 2"},{"key":3,"value":"Value 3"},{"key":4,"value":"Value 4"},{"key":5,"value":"Value 5"}]

So, for now all of your Controllers and ApiControllers can use your services.

That's all.

UPDATED:
You can download sources at: UnityApplication14.zip

March 26, 2012

ASP.NET MVC 4 WebAPI. Support Areas in HttpControllerFactory

This article was written for ASP.NET MVC 4 Beta. If you are using Release Candidate version of ASP.NET MVC 4 then you have to read the next article.

Unfortunately DefaultHttpControllerFactory doesn't support Areas by default.
To support it you have to write your HttpControllerFactory from scratch.

In this post i will show you how you can do it.

AreaHttpControllerFactory


First of all, you have to implement IHttpControllerFactory interface:
    public class AreaHttpControllerFactory : IHttpControllerFactory
    {
        public IHttpController CreateController(HttpControllerContext controllerContext, string controllerName)
        {
            throw new NotImplementedException();
        }

        public void ReleaseController(IHttpController controller)
        {
            throw new NotImplementedException();
        }
    }
We will implement two obligatory methods CreateController and ReleaseController later.

Let's start with fields and constructor:
        private const string ControllerSuffix = "Controller";
        private const string AreaRouteVariableName = "area";

        private IHttpControllerFactory _defaultFactory;
        private HttpConfiguration _configuration;
        private Dictionary<string, Type> _apiControllerTypes;

        public AreaHttpControllerFactory(HttpConfiguration configuration)
        {
            _configuration = configuration;
            _defaultFactory = new DefaultHttpControllerFactory(configuration);
        }
Our class is wrapper around DefaultHttpControllerFactory.
I hope i don't need to explain meaning of ControllerSuffix constant. But I would like to explain the AreaRouteVariableName constant - it contains the name of the variable which we will use to specify area name  in Routes collection.

In the _apiControllerTypes we will store all the API controllers types, so let's create private property:
        private Dictionary<string, Type> ApiControllerTypes
        {
            get
            {
                if (_apiControllerTypes != null)
                {
                    return _apiControllerTypes;
                }

                var assemblies = AppDomain.CurrentDomain.GetAssemblies();

                _apiControllerTypes = assemblies.SelectMany(a => a.GetTypes().Where(t => !t.IsAbstract && t.Name.EndsWith(ControllerSuffix) && typeof(IHttpController).IsAssignableFrom(t))).ToDictionary(t => t.FullName, t => t);

                return _apiControllerTypes;
            }
        }

This code, just takes all the API controllers types from all of your assemblies, and store it inside the dictionary, where the key is FullName of the type and value is the type itself.
Of course we will set this dictionary only once. And then just use it.

Now we are ready to implement the one of our main methods. I will start with ReleaseController method:
        public void ReleaseController(IHttpController controller)
        {
            _defaultFactory.ReleaseController(controller); 
        }
Easy.

The last method will do all the "magic" for us:
        public IHttpController CreateController(HttpControllerContext controllerContext, string controllerName)
        {
            var controller = GetApiController(controllerContext, controllerName);
            return controller ?? _defaultFactory.CreateController(controllerContext, controllerName);
        }
Easy as well. :)
And the method which will find the controller for us:
        private IHttpController GetApiController(HttpControllerContext controllerContext, string controllerName)
        {
            if (!controllerContext.RouteData.Values.ContainsKey(AreaRouteVariableName))
            {
                return null;
            }

            var areaName = controllerContext.RouteData.Values[AreaRouteVariableName].ToString().ToLower();
            if (string.IsNullOrEmpty(areaName))
            {
                return null;
            }

            var type = ApiControllerTypes.Where(t => t.Key.ToLower().Contains(string.Format(".{0}.", areaName)) && t.Key.EndsWith(string.Format(".{0}{1}", controllerName, ControllerSuffix), StringComparison.OrdinalIgnoreCase)).Select(t => t.Value).FirstOrDefault();
            if (type == null)
            {
                return null;
            }

            return CreateControllerInstance(controllerContext, controllerName, type);
        }
So, if an area variable is specifying in RouteData.Values and this variable is not null or not empty, then it tries to find the controller in the ApiControllerTypes by full name of the controller where the full name contains area's name surrounded by "." (e.g. ".Admin.") and ends with controller name + controller suffix (e.g. UsersController).
If the controller type is found, then it will calls CreateControllerInstance method. Otherwise, the method will return null.

And the code for CreateControllerInstance:
        private IHttpController CreateControllerInstance(HttpControllerContext controllerContext, string controllerName, Type controllerType)
        {
            var descriptor = new HttpControllerDescriptor(_configuration, controllerName, controllerType);
            controllerContext.ControllerDescriptor = descriptor;
            var controller = descriptor.HttpControllerActivator.Create(controllerContext, controllerType);
            controllerContext.Controller = controller;
            return controller;
        }

Registering AreaHttpControllerFactory


The next thing you have to do is to say to your application to use this controller factory instead of DefaultHttpControllerFactory. And fortunately it is really easy - just add one additional line to the end of Application_Start method in Glogal.asax file:
        protected void Application_Start()
        {
            // your default code

            GlobalConfiguration.Configuration.ServiceResolver.SetService(typeof(IHttpControllerFactory), new AreaHttpControllerFactory(GlobalConfiguration.Configuration));
        }
That's all.

Using AreaHttpControllerFactory

If you did everything right, now you can forget about that "nightmare" code. And just start to use it!

You have to add new HttpRoute to your AreaRegistration.cs file:
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.Routes.MapHttpRoute(
                name: "Admin_Api",
                routeTemplate: "api/admin/{controller}/{id}",
                defaults: new { area = AreaName, id = RouteParameter.Optional }
            );

            // other mappings
        }

That's all. Good luck, and have a nice day.

March 14, 2012

ASP.NET MVC 4 WebAPI authorization

In the examples of ASP.NET MVC 4 WebAPI you can find that authorization is really easy.
You just have to add [Authorize] attribute to your controller or for some actions which need it.

And if you do this you will expect that your WebAPI will return error code 401 (Not authorized) to your client.

But unfortunately it's not happened.
And you can ask: what will happen in the real world?
I can answer: your browser just get the 302 (Found) status code and will redirect you to the login page.

I think it's not expected behavior for you. Because you want to get just 401 status code in the client.

And I can show you how you can achieve it.

1. Please, double sure that you use AuthorizeAttribute from the System.Web.Http library instead of one from the System.Web.Mvc.

2. Add a directory and two classes to your code which should "FIX" it:

- Add App_Start directory to your solution.
       We will create two classes in this directory in a minute.

Add first class into that folder:  
       This class is a HTTP module which do all the 'magic'.
       The 'magic' is simple - just set the marker in PosrReleaseRequestState event if this is an ajax request and if our action returns status code equals to 401 (Unauthorized) or 403 (Forbidden). Then in OnEndRequest we have to check is this marker exists, and if yes, then set the returned status code from an action back.
public class AjaxFormsAuthenticationModule : IHttpModule

    {

        private const string FixupKey = "__WEBAPI:Authentication-Fixup";

        public void Dispose()

        {

        }

        public void Init(HttpApplication context)

        {

            context.PostReleaseRequestState += OnPostReleaseRequestState;

            context.EndRequest += OnEndRequest;

        }

        private void OnPostReleaseRequestState(object source, EventArgs args)

        {

            var context = (HttpApplication)source;

            var response = context.Response;

            var request = context.Request;

            bool isAjax = request.Headers["X-Requested-With"] == "XMLHttpRequest";

            if ((response.StatusCode == 401 || response.StatusCode == 403) && isAjax)

            {

                context.Context.Items[FixupKey] = response.StatusCode;

            }

        }

        private void OnEndRequest(object source, EventArgs args)

        {

            var context = (HttpApplication)source;

            var response = context.Response;

            if (context.Context.Items.Contains("__WEBAPI:Authentication-Fixup"))

            {

                response.StatusCode = (int)context.Context.Items[FixupKey];

                response.RedirectLocation = null;

            }

        }

    }

Add second class into that folder:
       This class will just register our HTTP module for our application..
using Microsoft.Web.Infrastructure.DynamicModuleHelper;

[assembly: PreApplicationStartMethod(typeof(FormsAuthenticationFixer), "Start")]

namespace LoginVS11.App_Start

{

    public static class FormsAuthenticationFixer

    {

        public static void Start()

        {

            DynamicModuleUtility.RegisterModule(typeof(AjaxFormsAuthenticationModule));

        }

    }

}

That's all.

After that all of your ajax requests will get the 401 status code if your client is not authorized yet.

March 5, 2012

ASP.NET MVC 4. Real application. Design, develop, testing.

In the next several posts i will show you how to create a real application in ASP.NET MVC 4.

I will try to cover all the aspects of creating an application.

I will start from design, where i will explain some general patterns.

Then I will show you how you can work with data through Entity Framework Code First, how you can migrate your database via Fluent Migrator.

Then the general principles of jQuery and jQuery UI. How you can create a version of your UI for mobile devices.

The last but not least - unit and integration testing of your application using Moq library and using database migration.


Table of contents:

  1. Design your application in ASP.NET MVC 4. (coming soon)
  2. General patterns - Repository, UnitOfWork. (coming soon)
  3. Entity Framework Code First in action. (coming soon)
  4. Database migrations with Fluent Migrator. (coming soon)
  5. Testing your repositories. (coming soon)
  6. Services via Web API. (coming soon)
  7. Business logic of the application. (coming soon)
  8. Unit testing using Moq library. (coming soon)
  9. Authentication and authorization with jQuery (coming soon)
  10. UI with jQuery. (coming soon)
  11. UI for mobile devices. (coming soon)
  12. Testing your UI. (coming soon)
  13. Create installation with Wix. (coming soon)

March 4, 2012

ASP.NET MVC 4 Beta has been relesed


Top Features

  • ASP.NET Web API
  • Refreshed and modernized default project templates
  • New mobile project template
  • Many new features to support mobile apps
  • Recipes to customize code generation
  • Enhanced support for asynchronous methods

You can read a detailed information at:
ASP.NET MVC official site

Download

You can download ASP.NET MVC 4 Beta for Visual Studio 2010:

Or you can download Visual Studio 11 Beta (includes ASP.NET MVC 4 Beta):