in

Chennai .Net User Group

A platform that enables you to Learn, Share & Grow (India's first .Net user group)

Shiju Varghese's Blog

  • Tips and Important Steps for Migrating Apps to Windows Azure

     The following are the few important steps and tips for migrating ASP.NET apps to Windows Azure.

    1. Convert the ASP.NET application into a Web Role project.
    2. Verify that the application is running correctly in the development environment.
    3. Make sure that your application is 64-bit compatible since Window azure is a 64-bit environment.
    4. Since Window Azure Web Roles runs on IIS7 Integrated mode, make sure that your web application does not have any issues with running on IIS 7 Integrated mode.
    5. If your web app is using Session, Membership, Roles and Profile data, you have to find a way to make the state information is working with Windows Azure environment. You can use ASP.NET Universal Providers for handling Session, Membership, Roles and Profile which will be working with Sql Azure. The Windows Azure Caching Service is also providing a provider for ASP.NET Session state which will be faster than working with Sql Azure, but will be bit expensive than using Sql Azure.
    6. If you are using ASP.NET caching, it would be recommended to use The Windows Azure Caching Service. The Windows Azure Caching Service is the better way to use Caching in Windows Azure.
    7. Upload and save files to BLOB storage, if your web application is dealing with documents, media files, etc.
    8. If your application is using any Windows services or using any background processing, migrate these services to Worker Roles.
    9. Put messages to Windows Azure storage Queue or Service Bus Queue if you want to communicate between Web Role and Worker Role.
    10. If you want to make federated claims-based authentication and single sign-on, you can use Windows Azure Access Control Service (ACS) that enables federated authentication. It will work with external identity providers such as Windows Live, Google, Facebook, and Open ID and you can also able to define service identities in ACS that lets you to authenticate without using an external identity provider.
    11. Use startup tasks if you want to perform operations and install components before your Azure Role starts on Virtual Server. You can add startup tasks by editing the ServiceDefinition.csdef file.
    12. Consider moving out some configuration settings in web.config files to ServiceConfiguration.cscfg so that you do not require redeployment after every change in configuration. Data in the ServiceConfiguration.cscfg file can be edited at runtime.
    13. The Windows Azure environment does not provide a SMTP relay or mail relay service. So if your application is using e-mail services, it would be recommended to use a third party service (like SendGrid or AuthSMTP) to send email from inside Windows Azure.
    14. If you are using Sql Azure, use a SQL Server 2008 R2 client so that you can easily migrate database schema and data into Sql Azure. And you can connect the Sql Azure from the SQL Server 2008 R2 client.


     


  • Building a Windows Azure App using Azure Queue, Azure Table and ASP.NET MVC Web Role

    In this post, I will demonstrate a Windows Azure app using Azure Queue, Azure Table and a ASP.NET MVC 4 Web Role application. This post is explaining few initial steps for building a demo Azure app where asynchronous commands (write operations that changes the data) put into Azure Queue and an Azure Work Role will persist the data into Azure Table from Queue messages for the read operations. The source code is available from http://azurehack.codeplex.com/ .The demo application will modify and add more functionality on later.

    Windows Azure Storage Services


    The Windows Azure storage services provide the following services that are secure, scalable and easy to access that remain persistent and durable storage in the cloud.

    Binary Large Object (BLOB) – BLOB service is the file system in the cloud which provide storage for large pieces of data, such as images, video, documents etc. BLOB is the simplest way to store text or binary data on Windows Azure.

    Tables – Windows Azure Table Storage Service provides queryable structured storage.Table Storage service is very similar to NoSQL databases that lets you to massively scalable your apps.

    Queues – Queue service provides reliable storage and delivery of messages and can be use for messaging between Web and Worker role instances.

    Drives – Windows Azure Drive provides durable NTFS volumes for Windows Azure applications.

    Demo Windows Azure App

    In our demo app, all database write commands will be perform in an asynchronous way and these command messages will send  to Azure Queue.  A worker role will retrieve the Queue messages and will persist the data into Azure Table. The web role app is built with ASP.NET MVC 4. In this simple demo app, we are creating Customer entity data and these data will list  in a AS.NET MVC view page from a Azure Table. The request for creating a new Customer data will write a message to Azure Queue. The below class is representing the write command for creating new Customer

    public class NewCustomerCommand : AzureQueueMessage
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Address { get; set; }
            public string Phone { get; set; }
            public string Email { get; set; }
        }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

     

    The new NewCustomerCommand is inherited from a  class AzureQueueMessage. The AzureQueueMessage class is the base class for the Azure Queue messages.The AzureQueueMessage class is shown below

    public abstract class AzureQueueMessage
    {
        public string Id { get; set; }
        public string PopReceipt { get; set; }
        public int DequeueCount { get; set; }
        public DateTime? InsertionTime { get;  set; }
        public DateTime? ExpirationTime { get; set; }
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    We are using strongly typed Azure Queue message. The below code block shows the contract type for our strongly type Azure Queue

    public interface IAzureQueue<T> where T : AzureQueueMessage
    {
        void EnsureExist();
        void Clear();
        void AddMessage(T message);
        T GetMessage();
        T GetMessage(TimeSpan timeout);
        IEnumerable<T> GetMessages(int maxMessagesToReturn);
        void DeleteMessage(T message);
        void DeleteMessage(CloudQueueMessage message);
        void DeleteQueue();
        int ApproximateMessageCount { get; }
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

     

    Creating Queue messages from ASP.NET MVC Controller

    The below code block in the ASP.NET MVC action method will create the strongly typed queue message with type NewCustomerCommand. The write command NewCustomerCommand  is representing the operation for  creating a new Customer entity.

    CloudStorageAccount account;
    public CustomerController()
    {
        account = CloudStorageAccount.
             FromConfigurationSetting("DataConnectionString");
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
    [HttpPost]
    public ActionResult Create(CustomerFormModel formModel)
    {
    if (ModelState.IsValid)
    {
        AzureQueue<NewCustomerCommand> queue = new 
                            AzureQueue<NewCustomerCommand>(account);
        queue.AddMessage(new NewCustomerCommand
        {
            FirstName = formModel.FirstName,
            LastName = formModel.LastName,
            Address = formModel.Address,
            Phone = formModel.Phone,
            Email = formModel.Email
        });              
    return RedirectToAction("Index");
    }
     return View(formModel);
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

     

    The class AzureQueue is a strongly typed Azure Queue. We are adding a message to the Queue with the information of  NewCustomerCommand. A worker role will look on the Queue message and will perform the operations for our command.

    Processing Queue messages in Worker Role

    The Worker Role is similar to a windows service and mainly using for background processing. In our application, we are using the Worker Role for processing the Queue message send from Web Role application. The Azure Queue is a great way to communicate between Web Role and Worker Role.

    In the following code block in Worker Role, we are creating a strongly typed Queue with NewCustomerCommand and getting the unprocessed Queue messages from the Queue. After that, the data of the each Queue message is using for creating a Customer entity and will persist this data into Azure Table. The Table storage can be use for read operations of our application. We are deleting the Queue message after persisting the Customer entity into Azure Table.

    var account = CloudStorageAccount.
    FromConfigurationSetting("DataConnectionString");
    AzureQueue<NewCustomerCommand> queue = new 
       AzureQueue<NewCustomerCommand>(account);
    queue.EnsureExist();            
                
    while (true)
    {
    try
    {
     var message = queue.GetMessage();                    
     if (message != null)
      {
            
    AzureTable<Customer> table = new AzureTable<Customer>(account);
        var guiid= Guid.NewGuid().ToString();
        table.AddEntity( new Customer
        {
            Id = Guid.NewGuid().ToString(),
            PartitionKey = guiid,
            RowKey = message.FirstName,
            FirstName = message.FirstName,
            LastName=message.LastName,
            Address=message.Address,
            Phone=message.Phone,
            Email=message.Email 
        });
        queue.DeleteMessage(message);
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
        }
        }
        catch { }
        Thread.Sleep(5000);
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    We are using a Azure Table entity Customer for persisting the Customer data. The Customer Table entity is shown below

    public class Customer : TableServiceEntity
    {
        public string Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
    }

    The Customer entity is inherited from TableServiceEntity for making the Customer entity as a Azure Table. The TableServiceEntity provides properties PartionKey, RowKey and Timestamp. The server manages the value of Timestamp, which cannot be modified. We need to update the values of PartitionKey and RowKey.The partition key is a unique identifier for the partition within a given table, specified by the PartitionKey property. The partition key forms the first part of an entity's primary key. The second part of the primary key is the row key, specified by the RowKey property. The row key is a unique identifier for an entity within a given partition. Together the PartitionKey and RowKey uniquely identify every entity within a table.

    The AzureTable class is using for the all CRUD operations for Azure Table. The below code block shown the contract type of AzureTable class.

    public interface IAzureTable<TEntity> where TEntity : TableServiceEntity
    {
        IQueryable<TEntity> Query { get; }
        bool CreateIfNotExist();
        bool DeleteIfExist();
        void AddEntity(TEntity obj);
        void AddEntity(IEnumerable<TEntity> objs);
        void AddOrUpdateEntity(TEntity obj);
        void AddOrUpdateEntity(IEnumerable<TEntity> objs);
        void DeleteEntity(TEntity obj);
        void DeleteEntity(IEnumerable<TEntity> objs);
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    Reading the data in ASP.NET MVC App

    We are showing the Customer data from Azure table and periodically refresh the data using Ajax. The following code in the ASP.NET MVC action method querying the data from Azure Table Customer.

    public ActionResult Index()
    {
      AzureTable<Customer> table = new AzureTable<Customer>(account);
      var customers = table.Query;
      if (Request.IsAjaxRequest())
      {
         return PartialView("_List", customers);
      }
     return View(customers);
    }
     

    Since our write command is working in an asynchronous way, we are refreshing the view page periodically using Ajax for latest data

    @model IEnumerable<AzureHacks.Domain.Models.Customer>
    @{
        ViewBag.Title = "Index";
    }
    <h2>Index</h2>
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <div id="CustomerList">
    @Html.Partial("_List", Model)
    </div>
     <script type="text/javascript">
    $(function () {
    setInterval(function () {
     $.get('@Url.Action("Index")', {}, function (view) {
        $("#CustomerList").html(view);
      })
     },5000);
    });
    </script>   

    Source Code

    The source code can be download from http://azurehack.codeplex.com/

    Summary

    This post is an initial step for building a demo app on the Windows Azure. We have discussed Azure storage services Queue and Table and explored the Worker Role for processing Queue messages. Azure Queue is a great way to communicate between Web Role and Worker Role. And the Azure Table is providing a great way to store massively scalable structured data that is available for querying the data. We are are performing our commands in an asynchronous way  and Azure Table is using for our read operations.

  • Startup Tasks for Windows Azure Roles

    Windows Azure supports startup tasks that can be use to perform operations and install components before your Azure Role starts on Virtual Server. You can use to startup tasks to install other software, register COM components, setting registry keys, start another process, etc. This is very useful in many situations where you might want to running an initialization scripts, execute batch files and PowerShell scripts etc before your Role starts. In the past, I had used a startup task to install ASP.NET MVC 3 when ASP.NET MVC 3 web role was not supported. You can add startup tasks by editing the ServiceDefinition.csdef file. The below configuration in the Service Definition  file will add a startup task.

    <?xml version="1.0" encoding="utf-8"?>
    <ServiceDefinition name="AzureDemo" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WebRole name="WebRole1" vmsize="Small">
        <Startup>
         <Task commandLine="install.cmd" executionContext="elevated" />
        </Startup>
     <!--Other Configurations below-->
       </WebRole>
    </ServiceDefinition>

    The above configuration added a batch file install.cmd as a startup task. You should add the batch file install.cmd onto your Azure Role project. The executionContex attribute specifies the permission level.This value can be limited or elevated. The elevated execution context enables administrator level permission and limited level permission gives non-admin level permission. Windows Azure will look for the bin folder for the startup tasks. So you should specify the batch file as “Copy to Output Directory” in Visual Studio so that the batch file will be copied to bin folder of your Azure Role. In our example, the batch file install.cmd will be executed before the Azure role  starts.

  • Visual Studio Enhancements in Windows Azure SDK 1.6 for Publishing Apps

    The new Windows Azure SDK 1.6 is providing many enhancements including a better experience for publishing Windows Azure applications using Visual Studio. To publish an application onto Azure, do the following steps.

    First right click on the Azure project from Visual Studio and Select Publish. The below publish window will show.

    Publish_SignIn

     

    When you run the publish wizard  for the first time, you must download your credentials from Windows Azure portal. Choose the Sign In To Download Credentials link from the Sign in window. This will redirects to Windows Azure portal which will  generate a publish-settings file for you to download. This will be generated a file and prompt for download the file from the location https://windows.azure.com/download/publishprofile.aspx . The generated file will be en extension with publishsettings which contains the credentials and subscriptions information. After download the file, you need to import the publish-settings file into the Windows Azure publish window. Then you can chose a subscription from the populated subscriptions drop down and proceed.

    The next step is setting the publication settings. In the Settings window, we can select a service to deploy or create a new hosted service. The below window shows the option for create a new Windows Azure hosted service. To create a new hosted service, give the hosted service name and the location. The new feature lets the Azure developers to create hosted service accounts without going to Windows Azure portal.

    azure_newhosterservice

    In the Settings Window, we can set hosted service, cloud environment  (production or staging), the build configuration (release or debug), and the Service configuration file (cloud or local) to be used. We also can select the Advanced Settings tab to specify the deployment label, storage account information etc. We can also able to setting up remote desktop by checking the  related checkbox. The below windows shows the Remote Desktop Configuration.

    rdcide


    Click the next button after completing the Settings, this will show the summary details of settings we had just specified and it will save the all information as new profile. You can use these settings when we are publishing the project again. The final step is to click the publish button. This will proceed the publish and deploy our application onto Windows Azure.

    Summary 

    The new Windows Azure SDK 1.6 is providing a better developer experience for deploying Windows Azure  apps from Visual Studio. The new features lets the Visual Studio developers to deploy Windows Azure apps without touching the Windows Azure portal. We can now create hosted services and able to specify all the settings to deploy apps to Azure from Visual Studio itself that lets better productivity to the Azure developers.

  • CQRS, Commands, Command Handlers and Command Dispatcher

    In this post, I am trying to add some CQRS principles onto my EFMVC project. Please keep in mind that this is not the implementation CQRS patterns, but trying to add some CQRS flavors on the Solution Architecture with Commands that changes the data (Create, Update and Delete). The current implementation of command execution is implemented in a synchronous way. 

    CQRS 

    CQRS is stands for Command-Query Responsibility Segregation that is a principle of separating commands (that change the data) from queries (that read the data). The CQRS pattern is first described by Greg Young and his blog post CQRS, Task Based UIs, Event Sourcing agh! has explained about this approach. If you want to build real world CRQS based apps, I highly recommending to read Rinta Abdullin's blog and the CQRS info site.

    Domain Entity

    The below domain entity Category is using for demo  application

    public class Category
    {
        public int CategoryId { getset; }
        [Required]
        public string Name { getset; }
        public string Description { getset; }
    }

     
    Command


    Every write operations represent a command and these commands will be executed by using a Command Handler.  Let’s add command object CreateOrUpdateCategoryCommand for representing the Create and Update write operation.

    public class CreateOrUpdateCategoryCommand : ICommand
    {
        public CreateOrUpdateCategoryCommand(int CategoryId,string name, string description)
        {
            this.CategoryId = CategoryId;
            this.Name = name;
            this.Description = description;
        }
        public int CategoryId { getset; }
        public string Name { getset; }
        public string Description { getset; }
    }


    The interface ICommand is now just using for IoC purpose to hook corresponding Command Handler object.

    public interface ICommand  { }
    

    Command Handler


     The following code is shown the Command Handler for the command object CreateOrUpdateCategoryCommand.

    public class CreateOrUpdateCategoryHandler : ICommandHandler<CreateOrUpdateCategoryCommand>
    {
        private readonly ICategoryRepository categoryRepository;
        private readonly IUnitOfWork unitOfWork;
        public CreateOrUpdateCategoryHandler(ICategoryRepository categoryRepository, IUnitOfWork unitOfWork)
        {
            this.categoryRepository = categoryRepository;
            this.unitOfWork = unitOfWork;
        }
        public ICommandResult Execute(CreateOrUpdateCategoryCommand command)
        {
            var category = new Category
            {
                CategoryId = command.CategoryId,
                Name = command.Name,
                Description = command.Description
            };
            if (category.CategoryId == 0)
                categoryRepository.Add(category);
            else
                categoryRepository.Update(category);
            unitOfWork.Commit();
            return new CommandResult(true);
        }
    }

     The CreateOrUpdateCategoryHandler object will do the data persistence for the command operation CreateOrUpdateCategoryCommand.

    The ICommandHandler<T> interface is shown below

     public interface ICommandHandler<in TCommand> where TCommand: ICommand
        {
            ICommandResult Execute(TCommand command);
        }

     Command Validator


    Every command object would be submitted to a Command Bus that will be hook the right command handler and will execute the command operation. In this demo app, we just validate the command before submitting the command to command bus.


    The following is Validator for our command CreateOrUpdateCategoryCommand

    public class CanAddCategory : IValidationHandler<CreateOrUpdateCategoryCommand>
    {
        private readonly ICategoryRepository categoryRepository;      
        public CanAddCategory(ICategoryRepository categoryRepository, IUnitOfWork unitOfWork)
        {
            this.categoryRepository = categoryRepository;           
        }
        public IEnumerable<ValidationResult> Validate(CreateOrUpdateCategoryCommand command)
        {
            Category isCategoryExists=null;
            if(command.CategoryId==0)
                isCategoryExists = categoryRepository.Get(c => c.Name == command.Name);
            else
                isCategoryExists = categoryRepository.Get(c => c.Name == command.Name && c.CategoryId!=command.CategoryId);
            if (isCategoryExists!=null )
            {
                yield return new ValidationResult("Name"Resources.CategoryExists);
            }
        }
    }

     
    The IValidationHandler<T> interface is shown below

    public interface IValidationHandler<in TCommand> where TCommand : ICommand
    {
        IEnumerable<ValidationResult>  Validate(TCommand command);
    }


    Command Dispatcher


    The responsibility of the Command Dispatcher object is to hook right Command Handler object based on the command object we have submitted to the Command Dispatcher object. Autofac IoC container is using to hook the Command Handler object for the given command object.
    The following is the contract type of Command Dispatcher

    public interface ICommandBus
    {
        ICommandResult Submit<TCommand>(TCommand command) where TCommand: ICommand;
        IEnumerable<ValidationResult> Validate<TCommand>(TCommand command) where TCommand : ICommand;
    }

     
    The default implementation of the ICommandBus is shown below

    public class DefaultCommandBus : ICommandBus
    {
        public ICommandResult Submit<TCommand>(TCommand command) where TCommand: ICommand
        {    
            var handler = DependencyResolver.Current.GetService<ICommandHandler<TCommand>>();
            if (!((handler != null) && handler is ICommandHandler<TCommand>))
            {
                throw new CommandHandlerNotFoundException(typeof(TCommand));
            }  
            return handler.Execute(command);
     
        }
        public IEnumerable<ValidationResult> Validate<TCommand>(TCommand command) where TCommand : ICommand
        {
            var handler = DependencyResolver.Current.GetService<IValidationHandler<TCommand>>();
            if (!((handler != null) && handler is IValidationHandler<TCommand>))
            {
                throw new ValidationHandlerNotFoundException(typeof(TCommand));
            }  
            return handler.Validate(command);
        }
    }


    The command bus provides two methods – Submit and Validate. The submit method will execute the appropriate command handler object and the validate method is used for validating the command object before submitting the command. The default command bus object provides the command execution in a synchronous way. In many real world CQRS implementations, this would be in anasynchronous way.

    Component Registration in Autofac

    The following code is using in the EFMVC project to register components with Autofac.

    private static void SetAutofacContainer()
    {
        var builder = new ContainerBuilder();          
        builder.RegisterControllers(Assembly.GetExecutingAssembly());
        builder.RegisterType<DefaultCommandBus>().As<ICommandBus>().InstancePerHttpRequest();
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
        builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest();
        builder.RegisterAssemblyTypes(typeof(CategoryRepository).Assembly)
        .Where(t => t.Name.EndsWith("Repository"))
        .AsImplementedInterfaces().InstancePerHttpRequest();          
        var services = Assembly.Load("EFMVC.Domain");
        builder.RegisterAssemblyTypes(services)
        .AsClosedTypesOf(typeof(ICommandHandler<>)).InstancePerHttpRequest();
        builder.RegisterAssemblyTypes(services)
        .AsClosedTypesOf(typeof(IValidationHandler<>)).InstancePerHttpRequest();
        builder.RegisterType<DefaultFormsAuthentication>().As<IFormsAuthentication>().InstancePerHttpRequest();
        builder.RegisterFilterProvider();
        IContainer container = builder.Build();                  
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }


    ASP.NET MVC Controller 

    In our demo app, the command object CreateOrUpdateCategoryCommand is creating and submitting to Command Bus from a ASP.NET MVC controller action method. In the following action method, we are creating the CreateOrUpdateCategoryCommand object based form values and calling the Validate method of command bus. The command is valid, we will submit the command object to the Command Bus object and execute the command operation in a synchronous way.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Save(CategoryFormModel form)
    {
        if(ModelState.IsValid)
        {
            var command = new CreateOrUpdateCategoryCommand(form.CategoryId,form.Name, form.Description);
            IEnumerable<ValidationResult> errors=  commandBus.Validate(command);
            if (errors.Count() > 0)
            {
                ModelState.AddModelErrors(errors);
            }
            if (ModelState.IsValid)
            {
                var result = commandBus.Submit(command);
                if (result.Success) return RedirectToAction("Index");                 
            }                
        }   
        //if fail
        if (form.CategoryId == 0)
            return View("Create",form);
        else
            return View("Edit", form);
    }    

    Source Code

    You can download the source code from http://efmvc.codeplex.com/.  



  • EFMVC 1.0 Preview Released

    A while ago, I have released EFMVC, a demo web app built using ASP.NET MVC 3, EF Code First and Unity. The EFMVC app has demonstrated many architectural patterns and practices such as Generic Repository, Repository pattern, Unit of Work pattern, Dependency Injection pattern and Application Service later.  Today I would like to announce the release of EFMVC 1.0 Preview. This release is an early preview release that has made some changes in the solution architecture.  The preview is written in ASP.NET MVC 3 version and will be migrated to ASP.NET MVC 4 with new features on later.


    Changes in EFMVC 1.0


    In EFMVC 1.0, I have made some changes on the solution architecture. I have completely re-written the Application Service layer where I have added some CQRS flavor on the Solution Architecture. But please keep in mind that this is not the implementation of CQRS pattern. Now every write operations (Create, Update and Delete) represent a command and these commands will be executed by using a Command Handler. These command handlers would be hooked by a command dispatcher based on the command type. The following code in the Controller class is creating a Command object and will submit to the Command Bus. Before submitting the Command, we validate the Command object using the validate method of Command Bus.

     

    Code Snippet
    1. if(ModelState.IsValid)
    2. {
    3.     var command = new CreateOrUpdateCategoryCommand(form.CategoryId,form.Name, form.Description);
    4.     IEnumerable<ValidationResult> errors=  commandBus.Validate(command);
    5.     if (errors.Count() > 0)
    6.     {
    7.         ModelState.AddModelErrors(errors);
    8.     }
    9.     if (ModelState.IsValid)
    10.     {
    11.         var result = commandBus.Submit(command);
    12.         if (result.Success) return RedirectToAction("Index");                 
    13.     }                
    14. }

     The following code is shown the Command Handler for command object CreateOrUpdateCategoryCommand.

     

    Code Snippet
    1. public class CreateOrUpdateCategoryHandler : ICommandHandler<CreateOrUpdateCategoryCommand>
    2. {
    3.     private readonly ICategoryRepository categoryRepository;
    4.     private readonly IUnitOfWork unitOfWork;
    5.     public CreateOrUpdateCategoryHandler(ICategoryRepository categoryRepository, IUnitOfWork unitOfWork)
    6.     {
    7.         this.categoryRepository = categoryRepository;
    8.         this.unitOfWork = unitOfWork;
    9.     }
    10.     public ICommandResult Execute(CreateOrUpdateCategoryCommand command)
    11.     {
    12.         var category = new Category
    13.         {
    14.             CategoryId = command.CategoryId,
    15.             Name = command.Name,
    16.             Description = command.Description
    17.         };
    18.         if (category.CategoryId == 0)
    19.             categoryRepository.Add(category);
    20.         else
    21.             categoryRepository.Update(category);
    22.         unitOfWork.Commit();
    23.         return new CommandResult(true);
    24.     }
    25. }

     The right Command Handler would be hooked by a Command Dispatcher object based on the command type. The following code is shown the implementation of Command Dispatcher object.

     

    Code Snippet
    1. public class DefaultCommandBus : ICommandBus
    2. {
    3.     public ICommandResult Submit<TCommand>(TCommand command) where TCommand: ICommand
    4.     {    
    5.         var handler = DependencyResolver.Current.GetService<ICommandHandler<TCommand>>();
    6.         if (!((handler != null) && handler is ICommandHandler<TCommand>))
    7.         {
    8.             throw new CommandHandlerNotFoundException(typeof(TCommand));
    9.         }  
    10.         return handler.Execute(command);

    11.     }
    12.     public IEnumerable<ValidationResult> Validate<TCommand>(TCommand command) where TCommand : ICommand
    13.     {
    14.         var handler = DependencyResolver.Current.GetService<IValidationHandler<TCommand>>();
    15.         if (!((handler != null) && handler is IValidationHandler<TCommand>))
    16.         {
    17.             throw new ValidationHandlerNotFoundException(typeof(TCommand));
    18.         }  
    19.         return handler.Validate(command);
    20.     }
    21. }

     The current version is executing the command in synchronous way and future versions will be provide the support for executing the commands asynchronous way using a different architecture approach. The latest EFMVC version is using Autofac for dependency injection over Microsoft Unity.

    Source Code

    You can download the source code from http://efmvc.codeplex.com

  • Removing EdmMetadata table in EF Code First

     EF Code First Framework is using a table named EdmMetadata on the database to check the current model is compatible with the database. When your model is changing, you need to drop the database and create a new database. In that scenario, you can add a initialization strategy using DropCreateDatabaseIfModelChanges<TContext>. You can avoid the EdmMetadata table from your database so it won't check the schema of database with model. When you are using Code First Migrations or updating your database schema is manually, you don't need to EdmMetadata on the database. The following code in the DbContext class will not create EdmMetadata on the database.

     

    1. protected override void OnModelCreating(DbModelBuilder modelBuilder)
    2.         {
    3.             modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
    4.         }

     

  • Autofac - My Choice of IoC Container

    I have been using Unity for dependency injection since the early days of ASP.NET MVC framework. Recently I have evaluated other IoC containers and really impressed with Autofac. The next version of my codeplex project EFMVC will be use Autofac as IoC container.  Autofac is a lightweight IoC container that providing better performance and can easily integrate with .NET applications. Autofac is developed by Nicholas Blumhardt and the community is actively working on the code base.

    Using Autofac in ASP.NET MVC 3 Apps


    Autofac provides better integration for ASP.NET MVC Framework.You can add the Autofac ASP.NET MVC3 Integration package using NuGet to working with MVC 3. The following command in the NuGet console will add Autofac and its ASP.NET MVC 3 integration components.

    PM> Install-Package Autofac.Mvc3


    Register components with Autofac

    The following code block in the Application_Start()  of Global.asax.cs will configure Autofac  with ASP.NET MVC 3.

    var builder = new ContainerBuilder();          
    builder.RegisterControllers(Assembly.GetExecutingAssembly());    
    builder.RegisterType<CommandProcessor>().As<ICommandProcessor>();
    builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
    builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest();
    builder.RegisterAssemblyTypes(typeof(CategoryRepository).Assembly)
    .Where(t => t.Name.EndsWith("Repository"))
    .AsImplementedInterfaces().InstancePerHttpRequest();          
    var tasks = Assembly.Load("EFMVC.Tasks");
    builder.RegisterAssemblyTypes(tasks)
    .AsClosedTypesOf(typeof(ICommandHandler<>)).InstancePerHttpRequest(); 
    IContainer container = builder.Build();                  
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

    Registering Controllers

    The below code register all the controllers in an assembly

    builder.RegisterControllers(Assembly.GetExecutingAssembly());    
    


    Register components

    The following code will register components with container lifetime of Http Request

    builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
    builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest();


    Auto Registration


    Autofac will automatically register your components by scanning assembly The following registration syntax will register all types in an assembly where type name is end with "Repository".

    builder.RegisterAssemblyTypes(typeof(CategoryRepository).Assembly)
    .Where(t => t.Name.EndsWith("Repository"))
    .AsImplementedInterfaces().InstancePerHttpRequest(); 


    The following registration syntax will scan the given assembly and will register all types that implemented the open generic type ICommandHandler<>

    var tasks = Assembly.Load("EFMVC.Tasks");
    builder.RegisterAssemblyTypes(tasks)
    .AsClosedTypesOf(typeof(ICommandHandler<>)).InstancePerHttpRequest(); 

    Filter Attribute Property Injection


    To make use of property injection in filter attributes, just call the RegisterFilterProvider method provided by Autofac.MVC3

    builder.RegisterControllers(Assembly.GetExecutingAssembly());
    builder.RegisterFilterProvider();

     Useful Links

    Autofac Home

    Nicholas Blumhardt's Blog

    Rinat Abdullin's Blog

    Alex Meyer's Blog

    Improving Performance  

    Help from Stackoverflow

     

  • ASP.NET MVC 4 Enhancements to Default Project Templates

     The ASP.NET MVC 4 provides an additional project teamplate for Mobile Web Application. The new Project dialog is shown below

     


    The project templates that are used to create new ASP.NET MVC 4 projects have been updated and provide a nice and modern looking user interface. The home page using the new project template is shown below

     

     The new project template provides adaptive rendering for both desktop browsers and mobile browsers without any customization. The home page is displayed in the mobile browser is shown below

     

    The login screen is shown below

     



    Mobile Project Template


    The ASP.NET MVC 4 provides a new project template for Mobile Application for creating mobile specific websites. The new mobile project template is based on jQuery Mobile. Earlier I have blogged about building Mobile enabled web apps with ASP.NET MVC 3 and jQuery Mobile. The below is shown the mobile page rendered in a mobile browser

     

  • ASP.NET MVC 4 Developer Preview Released

     Microsoft has announced the availability of ASP.NET MVC 4 Developer Preview.  The following are the some of the new features of ASP.NET MVC 4 Developer Preview.

    •  Mobile Project Template based on jQuery Mobile
    •  Enhancements to Default Project Templates
    •  Recipes for Code Generation in Visual Studio
    •  Task Support for Asynchronous Controllers

    You can install the ASP.NET MVC 4 Developer Preview from here .
    For the Windows Azure, ASP.NET MVC 4 Developer Preview supports the September 2011 1.5 release of the Windows Azure SDK.

    The following are the few links about ASP.NET MVC 4

     

  • Auto Registration in Microsoft Unity

    Unlike many other .NET IoC containers, Microsoft Unity does not support auto registrations. Auto registration is a very useful feature for any IoC container and it would be very helpful in some specific contexts.  The Unity Auto Registration project in Codeplex will provide the support for automatic registration using a fluent API. You can add Unity Auto Registration package using NuGet. The following command will add reference to Unity Auto Registration.

    PM> Install-Package UnityAutoRegistration

    The following registration syntax will scan the all assemblies except system assemblies and will register all types that implemented the open generic type ICommandHandler<> 

    1. IUnityContainer container = new UnityContainer();
    2. container.ConfigureAutoRegistration()
    3.     .ExcludeSystemAssemblies()   
    4. .Include(type => type.ImplementsOpenGeneric(typeof(ICommandHandler<>)),
    5.     Then.Register().AsFirstInterfaceOfType().WithTypeName())
    6. .ApplyAutoRegistration();

     

  • Building JavaScript MVVM apps in ASP.NET MVC using KnockoutJS

    JavaScript is getting more attention in modern web application development and increasing the popularity of JavaScript on every day. HTML 5 is making a revolution in web apps world and it is becoming a common platform for variety of scenarios. JavaScript is the language for HTML 5. The next question is how we can write highly maintainable JavaScript code and how to write testable JavaScript code. The answer would be to use a high level JavaScript framework such as KnockoutJS, BackboneJS and SpineJS. In this post, I will demonstrate how to use KnockoutJS in your ASP.NET MVC apps. KnockoutJS is an open source JavaScript library developed by Steven Sanderson. I am a big admirer of Steven Sanderson so I decided to first evaluate  KnockoutJS  and really excited about the framework so far. You can download the source code of the demo app from here

    Introduction to KnockoutJS

    KnockoutJS is a JavaScript MVVM framework that lets you create very rich, highly responsive web apps using JavaScript and HTML. Using KnockoutJS, you can create desktop-like user interfaces for your web apps with JavaScript. KnockoutJS framework is based on the MVVM design pattern. MVVM is stands for  Model – View – View Model and it is a design pattern for UI, originally introduced with Silverlight and WPF. In JavaScript MVVM, Model would be your application’s stored data that would be implemented using a server-side technology. The View would be user interface with HTML. The View Model would be a JavaScript object which contains data and operations for your View. One of the nice features of KnockoutJS is the automatic UI refresh when your JavaScript model object changes. KnockoutJS is providing a functionality named observable that let you sync your JavaScript View Model object with user interfaces. KnockoutJS is provides an elegant binding mechanism that would bind user interface with JavaScript View Model object.

    Demo app with KnockoutJS

    You can add KnockoutJS using NuGet. The following command in NuGet console will install  KnockoutJS  on your web app.

    PM > install-package knockoutjs

    The following script reference will add a reference to Knockout.js on our ASP.NET MVC demo app.

    1. <script src="@Url.Content("~/Scripts/knockout-1.2.1.js")" type="text/javascript"></script>

    Let’s create an Model object in our ASP.NET MVC app

    1. public class Candidate
    2. {
    3.     public string FirstName { get; set; }
    4.     public string LastName { get; set; }        
    5.     public string Email { get; set; }
    6.     public int Experience { get; set; }
    7.     public string[] Technologies { get; set; }
    8. }

    View Model object in JavaScript

    Let’s create a JavaScript View Model object with name candiateModel for providing data to the user interface page

    1. var candidateModel = {
    2.     FirstName: ko.observable(''),
    3.     LastName: ko.observable(''),
    4.     Email: ko.observable(''),
    5.     Experience: ko.observable(0),
    6.     Technologies: ko.observableArray([]),
    7.     TechnologyToAdd: ko.observable('')
    8. };

    The View Model object in JavaScript contains properties which values are specified as ko.observable(). Knockout will automatically updates the UI when the view model changes. When our properties specified as  observable, Knockout will notify the changes to its subscribers and will automatically detect dependencies. The property Technologies is a array so that we specified it as observableArray. The observableArray is same as other observable, but it can contains array of values. In our above view model object, we initializes with empty values for properties. In our demo app, we need to show the full name of the Candidate when there is any change in FirstName or LastName. Let’s add a Name property to our view model object for automatically updates the UI when there is any change in name fields.

    1. candidateModel.Name = ko.dependentObservable(function () {
    2.     return candidateModel.FirstName() +
    3.     " " + candidateModel.LastName();
    4. });

    The Name property specified as dependentObservable because the Name property is dependent with other observable FirstName and LastName. Observables and dependent observables are key features of Knockout and the framework is doing automatic UI refresh using these features. Our view model candidateModel now contains the all properties for our UI. We need to add an operation for adding values to the Technologies array. The property TechnologyToAdd is using to represent the value for adding new technology to our array property Technologies. Let’s add an function to the view model for handling add technology operation.

    1. candidateModel.addTechnology = function () {
    2.     if (candidateModel.TechnologyToAdd() !== '') {
    3.         candidateModel.Technologies.push(candidateModel.TechnologyToAdd());
    4.         candidateModel.TechnologyToAdd('');
    5.     }
    6. };

    The above addTechnology function will add the value of TechnologyToAdd property to our array property Technologies.

    HTML View

    Now we have created a JavaScript view model object for our UI. Let’s add view elements to our View page.

    1. @{
    2.     ViewBag.Title = "Add Candidate";
    3. }
    4. <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    5. <script src="@Url.Content("~/Scripts/knockout-1.2.1.js")" type="text/javascript"></script>
    6. <form data-bind="submit: addCandidate">
    7.     <fieldset>
    8.         <legend>Candidate info</legend>
    9.         <p>First Name: <input type="text" data-bind="value: FirstName" /> </p>
    10.         <p>Last Name: <input type="text" data-bind="value: LastName" /> </p>
    11.         <p>Email:<input type="text" data-bind="value: Email" /> </p>
    12.         <p>Experience: <input type="text" data-bind="value: Experience" />&nbsp;months </p>         
    13.     </fieldset>
    14.     <fieldset>
    15.         <legend>Technologies</legend>
    16.         New Technology:
    17.         <input type="text" data-bind='value: TechnologyToAdd, valueUpdate: "afterkeydown"' />
    18.         <button type="submit" data-bind="enable: TechnologyToAdd().length > 0, click: addTechnology">Add</button>        
    19.     </fieldset>
    20.      <fieldset>
    21.    <legend>Candidate Profile</legend>
    22.     <b><span data-bind="text: Name"></span></b>
    23.     has <b><span data-bind="text: Experience"></span></b> month experience <br />  
    24.     Email : <b><span data-bind="text: Email"></span></b>
    25.     <p>Technology Expertises</p>
    26.         <select multiple="multiple" width="50" data-bind="options: Technologies"></select>    
    27.      </fieldset>     
    28.     <input type="submit" value="Create" />  
    29. </form>

    Declarative binding is the powerful features of KnockoutJS. The view elements are bind with our view model object. For data binding,  Knockout is using data-bind attribute to HTML elements.

    1. <input type="text" data-bind="value: FirstName" />

    The above input text is bind with view model object’s FirstName property.

    1. <span data-bind="text: Name"></span>

    The above HTML element bind with view model object’s Name property. The Name property will automatically updates when there is any change in FirstName or LastName fields.

    The button for adding new technology expertise is bind with addTechnology function of view model object.

    1. <button type="submit" data-bind="enable: TechnologyToAdd().length > 0, click: addTechnology">Add</button>

    The select element is bind with array property Technologies so that it automatically add items when there is any new item added to the Technologies property.

    1. <select multiple="multiple" width="50" data-bind="options: Technologies"></select>

    Activates KnockoutJS

    The below code in the JavaScript will activates KnockoutJS with our view model object. So it will bind the values of view model with HTML elements.

    1. ko.applyBindings(candidateModel);

    Save Candidate

    Let’s add a function to the view model for performing Ajax save using jQuery

    1. candidateModel.addCandidate = function () {
    2.     $.ajax({
    3.         url: "/Home/Create/",
    4.         type: 'post',
    5.         data: ko.toJSON(this),
    6.         contentType: 'application/json',
    7.         success: function (result) {
    8.             alert(result);
    9.         }
    10.     });
    11. };

    The form is bind with addCandidate function for submit

    1. <form data-bind="submit: addCandidate">

    Let’s add an action method Create for handling Ajax save functionality

    1. [HttpPost]
    2. public JsonResult Create(Candidate candidate)
    3. {
    4.     //do the persistence logic here
    5.     var message = "Candidate: " + candidate.FirstName + " Saved";
    6.     return Json(message);
    7. }

    Final View Model object

    The final JavaScript block is given below

    1. <script type="text/javascript">
    2. $(function () {
    3. //activates KO
    4. ko.applyBindings(candidateModel);
    5. });
    6. var candidateModel = {
    7.     FirstName: ko.observable(''),
    8.     LastName: ko.observable(''),
    9.     Email: ko.observable(''),
    10.     Experience: ko.observable(0),
    11.     Technologies: ko.observableArray([]),
    12.     TechnologyToAdd: ko.observable('')
    13. };    
    14. candidateModel.Name = ko.dependentObservable(function () {
    15.     return candidateModel.FirstName() +
    16.     " " + candidateModel.LastName();
    17. });
    18. candidateModel.addTechnology = function () {
    19.     if (candidateModel.TechnologyToAdd() !== '') {
    20.         candidateModel.Technologies.push(candidateModel.TechnologyToAdd());
    21.         candidateModel.TechnologyToAdd('');
    22.     }
    23. };
    24. candidateModel.addCandidate = function () {
    25.     $.ajax({
    26.         url: "/Home/Create/",
    27.         type: 'post',
    28.         data: ko.toJSON(this),
    29.         contentType: 'application/json',
    30.         success: function (result) {
    31.             alert(result);
    32.         }
    33.     });
    34. };
    35. </script>

    The UI Page on the browser

    The below screen shot shows the user interface of our demo app

    candidate_fullui

    The candidate profile section would be automatically refresh when there is any change in the input fields. 

    Source Code

    You can download the source code from here

    Summary

    KnockoutJS is an excellent JavaScript library that lets you to build desktop like user interface with JavaScript and HTML. This post is just an introductory post on KnockoutJS  and the real power of KnockoutJS is really exciting. You can get more details of KnockoutJS from the product web site http://knockoutjs.com. The knockout web site provides very nice documentation and lot of examples that would be very helpful to build real world web apps with KnockoutJS  and your favorite server-side and technology. You can build very exciting web apps with ASP.NET MVC and KnockoutJS.

  • Speaking at Kerala Microsoft User Group on JavaScript MVVM and KnockoutJS

    I will be speaking about JavaScript MVVM and KnockoutJS at Kerala Microsoft User Group, Kochi on August 20. In this session, I will provide an overview of KnockoutJS, a MVVM framework for creating rich, interactive  user interfaces with JavaScript and HTML. Finally, I will demonstrate how to use KnockoutJS in your ASP.NET/ASP.NET MVC applications. The event details  available from here.  

  • EF Code First Migrations August 2011 CTP Released

    EF Code First is a great ORM tool which lets you to develop applications in a Domain Driven approach. One of the pain point of EF Code First was the data migrations when your domain model is changing. Finally the ADO.NET team is providing a data migration solution for EF Code First that will incrementally evolve the database schema as you model changes over time. The ADO.NET team has released the CTP version of Code First migration solution named EF Code First Migrations August 2011 CTP. EF Code First Migrations is available as NuGet package named EntityFramework.SqlMigrations. The following command in the NuGet console will install the the EF Code First Migrations

    PM> Install-Package EntityFramework.SqlMigrations

    The EF Code First Migrations is providing different solutions for data migration that can be used for different requirement contexts.

    You can perform the following command in the NuGet console for maintaining your data after the model change.

    PM> Update-Database

    The following command will rename a column name Phone of Customer entity with ContactPhone


    PM> Update-Database -Renames:"Customer.Phone=>Customer.ContactPhone"

    Check out the ADO.NET team blog for more details about EF Code First Migrations August 2011.

  • User Activity logging in ASP.NET MVC app using Action Filter and log4net

    In this post, I will demonstrate how to use an action filter to log user tracking information in an ASP.NET MVC app. The below action filter will take logged user name, controller name, action name, timestamp information and the value of route data id. These user tracking information will be logged using log4net logging framework.

     

    1. public class UserTrackerAttribute : ActionFilterAttribute, IActionFilter
    2. {
    3.         
    4.     public override void OnActionExecuted(ActionExecutedContext filterContext)
    5.     {
    6.         var actionDescriptor= filterContext.ActionDescriptor;
    7.         string controllerName = actionDescriptor.ControllerDescriptor.ControllerName;
    8.         string actionName = actionDescriptor.ActionName;
    9.         string userName = filterContext.HttpContext.User.Identity.Name.ToString();
    10.         DateTime timeStamp = filterContext.HttpContext.Timestamp;
    11.         string routeId=string.Empty;
    12.         if (filterContext.RouteData.Values["id"] != null)
    13.         {
    14.             routeId = filterContext.RouteData.Values["id"].ToString();
    15.         }
    16.         StringBuilder message = new StringBuilder();
    17.         message.Append("UserName=");
    18.         message.Append(userName + "|");
    19.         message.Append("Controller=");
    20.         message.Append(controllerName+"|");
    21.         message.Append("Action=");
    22.         message.Append(actionName + "|");
    23.         message.Append("TimeStamp=");
    24.         message.Append(timeStamp.ToString() + "|");
    25.         if (!string.IsNullOrEmpty(routeId))
    26.         {
    27.             message.Append("RouteId=");
    28.             message.Append(routeId);
    29.         }
    30.         var log=ServiceLocator.Current.GetInstance<ILoggingService>();
    31.         log.Log(message.ToString());
    32.         base.OnActionExecuted(filterContext);
    33.     }
    34. }

    The LoggingService class is given below

    1. public class LoggingService : ILoggingService
    2.     {
    3.         private static readonly ILog log = LogManager.GetLogger
    4.             (MethodBase.GetCurrentMethod().DeclaringType);
    5.         public void Log(string message)
    6.         {
    7.             log.Info(message);
    8.         }
    9.     }
    10.     public interface ILoggingService
    11.     {
    12.         void Log(string message);
    13.     }

     

    The LoggingService class is using log4net framework for logging. You can add reference to log4net using NuGet.

    The following command on NuGet console will install log4net into your ASP.NET MVC app.

    PM> install-package Log4Net

    The below configuration information in web.config will configure log4net for using with Sql Server

    Let me add a log4net section to the <configSections> of web.config

    1. <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>

    The below is the log4net section in the web.config file

    1. <log4net>
    2.     <root>
    3.       <level value="ALL"/>
    4.       <appender-ref ref="ADONetAppender"/>
    5.     </root>
    6.     <appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender">
    7.       <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    8.       <connectionString value="data source=.\SQLEXPRESS;Database=MyFinance;Trusted_Connection=true;" />
    9.       <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />
    10.       <parameter>
    11.         <parameterName value="@log_date" />
    12.         <dbType value="DateTime" />
    13.         <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
    14.       </parameter>
    15.       <parameter>
    16.         <parameterName value="@thread" />
    17.         <dbType value="String" />
    18.         <size value="255" />
    19.         <layout type="log4net.Layout.PatternLayout" value="%thread" />
    20.       </parameter>
    21.       <parameter>
    22.         <parameterName value="@log_level" />
    23.         <dbType value="String" />
    24.         <size value="50" />
    25.         <layout type="log4net.Layout.PatternLayout" value="%level" />
    26.       </parameter>
    27.       <parameter>
    28.         <parameterName value="@logger" />
    29.         <dbType value="String" />
    30.         <size value="255" />
    31.         <layout type="log4net.Layout.PatternLayout" value="%logger" />
    32.       </parameter>
    33.       <parameter>
    34.         <parameterName value="@message" />
    35.         <dbType value="String" />
    36.         <size value="4000" />
    37.         <layout type="log4net.Layout.PatternLayout" value="%message" />
    38.       </parameter>
    39.     </appender>
    40.   </log4net>

     

    Configure log4net

    The below code in the Application_Start() of Global.asax.cs will configure the log4net

    1. log4net.Config.XmlConfigurator.Configure();

     

    The below Sql script is used for creating table in Sql Server for logging information

    CREATE TABLE [dbo].[Log] (
      [ID] [int] IDENTITY (1, 1) NOT NULL ,
      [Date] [datetime] NOT NULL ,
      [Thread] [varchar] (255) NOT NULL ,
      [Level] [varchar] (20) NOT NULL ,
      [Logger] [varchar] (255) NOT NULL ,
      [Message] [varchar] (4000) NOT NULL
    ) ON [PRIMARY]

More Posts Next page »
Copyright © 2002-2008 Chennai .Net User Group. All Rights Reserved. Microsoft and Microsoft logo's are trademarks of Microsoft Corporation