in

Chennai .Net User Group

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

Shiju Varghese's Blog

May 2010 - Posts

  • NoSQL with RavenDB and ASP.NET MVC - Part 1

     A while back, I have blogged NoSQL with MongoDB, NoRM and ASP.NET MVC Part 1 and Part 2 on how to use MongoDB with an ASP.NET MVC application. The NoSQL movement is getting big attention and RavenDB is the latest addition to the NoSQL and document database world. RavenDB is an Open Source (with a commercial option) document database for the .NET/Windows platform developed  by Ayende Rahien.  Raven stores schema-less JSON documents, allow you to define indexes using Linq queries and focus on low latency and high performance. RavenDB is .NET focused document database which comes with a fully functional .NET client API  and supports LINQ. RavenDB comes with two components, a server and a client API. RavenDB is a REST based system, so you can write your own HTTP cleint API. As a .NET developer, RavenDB is becoming my favorite document database. Unlike other document databases, RavenDB is supports transactions using System.Transactions. Also it's supports both embedded and server mode of database. You can access RavenDB site at http://ravendb.net

    A demo App with ASP.NET MVC

    Let's create a simple demo app with RavenDB and ASP.NET MVC. To work with RavenDB, do the following steps.

     

    1. Go to http://ravendb.net/download and download the latest build.
    2. Unzip the downloaded file.
    3. Go to the /Server directory and run the RavenDB.exe. This will start the RavenDB server listening on localhost:8080


    You can change the port of RavenDB  by modifying the "Raven/Port" appSetting value in the RavenDB.exe.config file.
    When running the RavenDB, it will automatically create a database in the /Data directory. You can change the directory name data by modifying "Raven/DataDirt" appSetting value in the RavenDB.exe.config file.

    RavenDB provides a browser based admin tool. When the Raven server is running, You can be access the browser based admin tool and view and edit documents and index using your browser admin tool. The web admin tool available at http://localhost:8080

     

     

     

     

    Working with ASP.NET MVC 

    To working with RavenDB in our demo ASP.NET MVC application, do the following steps

    Step 1 - Add reference to Raven Cleint API

    In our ASP.NET MVC application, Add a reference to the Raven.Client.Lightweight.dll from the Client directory.

    Step 2 - Create DocumentStore

    The document store would be created once per application. Let's create a DocumentStore on application start-up in the Global.asax.cs.

    documentStore = new DocumentStore { Url = "http://localhost:8080/" };

    documentStore.Initialise();


    The above code will create a Raven DB document store and will be listening the server locahost at port 8080   

    Step 3 - Create DocumentSession on BeginRequest  

    Let's create a DocumentSession on BeginRequest event in the Global.asax.cs. We are using the document session for every unit of work. In our demo app, every HTTP request would be a single Unit of Work (UoW).

    BeginRequest += (sender, args) =>

      HttpContext.Current.Items[RavenSessionKey] = documentStore.OpenSession();


    Step 4 - Destroy the DocumentSession on EndRequest

     

    EndRequest += (o, eventArgs) =>

    {

        var disposable = HttpContext.Current.Items[RavenSessionKey] as IDisposable;

        if (disposable != null)

            disposable.Dispose();

    };

     

    At the end of HTTP request, we are destroying the DocumentSession  object.

    The below  code block shown all the code in the Global.asax.cs

     

    private const string RavenSessionKey = "RavenMVC.Session";

    private static DocumentStore documentStore;

     

    protected void Application_Start()

    {

    //Create a DocumentStore in Application_Start

    //DocumentStore should be created once per application and stored as a singleton.

    documentStore = new DocumentStore { Url = "http://localhost:8080/" };

    documentStore.Initialise();

    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    //DI using Unity 2.0

    ConfigureUnity();

    }

     

    public MvcApplication()

    {

    //Create a DocumentSession on BeginRequest  

    //create a document session for every unit of work

    BeginRequest += (sender, args) =>

        HttpContext.Current.Items[RavenSessionKey] = documentStore.OpenSession();

    //Destroy the DocumentSession on EndRequest

    EndRequest += (o, eventArgs) =>

    {

    var disposable = HttpContext.Current.Items[RavenSessionKey] as IDisposable;

    if (disposable != null)

    disposable.Dispose();

    };

    }

     

    //Getting the current DocumentSession

    public static IDocumentSession CurrentSession

    {

      get { return (IDocumentSession)HttpContext.Current.Items[RavenSessionKey]; }

    }

     

    We have setup all necessary code in the Global.asax.cs for working with RavenDB. For our demo app,
    Let’s write a domain class

     

    public class Category

    {

     

        public string Id { get; set; }

     

        [Required(ErrorMessage = "Name Required")]

        [StringLength(25, ErrorMessage = "Must be less than 25 characters")]

        public string Name { get; set;}

        public string Description { get; set; }  


    }


    We have created simple domain entity Category. Let's create repository class for performing CRUD operations against our domain entity Category.

     

    public interface ICategoryRepository

    {

        Category Load(string id);

        IEnumerable<Category> GetCategories();

        void Save(Category category);

        void Delete(string id);      

    }

     

     

    public class CategoryRepository : ICategoryRepository

    {

        private IDocumentSession session;

        public CategoryRepository()

        {

                session = MvcApplication.CurrentSession;

        }

        //Load category based on Id

        public Category Load(string id)

        {

            return session.Load<Category>(id);

        }

        //Get all categories

        public IEnumerable<Category> GetCategories()

        {

            var categories= session.LuceneQuery<Category>()    

                .WaitForNonStaleResults()

                .ToArray();

            return categories;

     

        }

        //Insert/Update category

        public void Save(Category category)

        {

            if (string.IsNullOrEmpty(category.Id))

            {

                //insert new record

                session.Store(category);

            }

            else

            {

                //edit record

                var categoryToEdit = Load(category.Id);

                categoryToEdit.Name = category.Name;

                categoryToEdit.Description = category.Description;

            }

            //save the document session

            session.SaveChanges();

        }

        //delete a category

        public void Delete(string id)

        {

            var category = Load(id);

            session.Delete<Category>(category);

            session.SaveChanges();

        }       

    }


    For every CRUD operations, we are taking the current document session object from HttpContext object.

    session = MvcApplication.CurrentSession;

    We are calling the static method CurrentSession from the Global.asax.cs

    public static IDocumentSession CurrentSession

    {

        get { return (IDocumentSession)HttpContext.Current.Items[RavenSessionKey]; }

    }

     

    Retrieve Entities 

    The Load method get the single Category object based on the Id. RavenDB is working based on the REST principles and the Id would be like categories/1. The Id would be created by automatically when a new object is inserted to the document store. The REST uri categories/1 represents a single category object with Id representation of 1.  

    public Category Load(string id)

    {

       return session.Load<Category>(id);

    }

    The GetCategories method returns all the categories calling the session.LuceneQuery method. RavenDB is using a lucen query syntax for querying. I will explain more details about querying and indexing in my future posts.  

    public IEnumerable<Category> GetCategories()

    {

        var categories= session.LuceneQuery<Category>()    

            .WaitForNonStaleResults()

            .ToArray();

        return categories;

     

    }

    Insert/Update entity

    For insert/Update a Category entity, we have created Save method in repository class. If  the Id property of Category is null, we call Store method of Documentsession for insert a new record. For editing a existing record, we load the Category object and assign the values to the loaded Category object. The session.SaveChanges() will save the changes to document store. 

    //Insert/Update category

    public void Save(Category category)

    {

        if (string.IsNullOrEmpty(category.Id))

        {

            //insert new record

            session.Store(category);

        }

        else

        {

            //edit record

            var categoryToEdit = Load(category.Id);

            categoryToEdit.Name = category.Name;

            categoryToEdit.Description = category.Description;

        }

        //save the document session

        session.SaveChanges();

    }

     

    Delete Entity 

    In the Delete method, we call the document session's delete method and call the SaveChanges method to reflect changes in the document store. 

    public void Delete(string id)

    {

        var category = Load(id);

        session.Delete<Category>(category);

        session.SaveChanges();

    }

     

    Let’s create ASP.NET MVC controller and controller actions for handling CRUD operations for the domain class Category

     

    public class CategoryController : Controller

    {

    private ICategoryRepository categoyRepository;

    //DI enabled constructor

    public CategoryController(ICategoryRepository categoyRepository)

    {

        this.categoyRepository = categoyRepository;

    }

    public ActionResult Index()

    {  

     

        var categories = categoyRepository.GetCategories();

        if (categories == null)

            return RedirectToAction("Create");

        return View(categories);

    }

     

    [HttpGet]

    public ActionResult Edit(string id)

    {

        var category = categoyRepository.Load(id);    

        return View("Save",category);

    }

    // GET: /Category/Create

    [HttpGet]

    public ActionResult Create()

    {

        var category = new Category();

        return View("Save", category);

    }

    [HttpPost]

    public ActionResult Save(Category category)

    {

        if (!ModelState.IsValid)

        {

            return View("Save", category);

        }

     

            categoyRepository.Save(category);

            return RedirectToAction("Index");

     

     

    }       

    [HttpPost]

    public ActionResult Delete(string id)

    {

        categoyRepository.Delete(id);

        var categories = categoyRepository.GetCategories();

        return PartialView("CategoryList", categories);   

     

    }       

    }

     

    RavenDB is an awesome document database and I hope that it will be the winner in .NET space of document database world.  The source code of demo application available at http://ravenmvc.codeplex.com/


  • Dependency Injection in ASP.NET MVC NerdDinner App using Unity 2.0

    In my previous post Dependency Injection in ASP.NET MVC NerdDinner App using Ninject, we did dependency injection in NerdDinner application using Ninject. In this post, I demonstrate how to apply Dependency Injection in ASP.NET MVC NerdDinner App using Microsoft Unity Application Block (Unity) v 2.0.

    Unity 2.0

    Unity 2.0 is available on Codeplex at http://unity.codeplex.com . In earlier versions of Unity, the ObjectBuilder generic dependency injection mechanism, was distributed as a separate assembly, is now integrated with Unity core assembly. So you no longer need to reference the ObjectBuilder assembly in your applications. Two additional Built-In Lifetime Managers - HierarchicalifetimeManager and PerResolveLifetimeManager have been added to Unity 2.0.

    Dependency Injection in NerdDinner using Unity

    In my Ninject post on NerdDinner, we have discussed the interfaces and concrete types of NerdDinner application and how to inject dependencies through controller constructors. The following steps will configure Unity 2.0 to apply controller injection in NerdDinner application.

    Step 1 – Add reference for Unity Application Block

    Open the NerdDinner solution and add  reference to Microsoft.Practices.Unity.dll and Microsoft.Practices.Unity.Configuration.dll
    You can download Unity from at http://unity.codeplex.com .

    Step 2 – Controller Factory for Unity

    The controller factory is responsible for creating controller instances.We extend the built in default controller factory with our own factory for working Unity with ASP.NET MVC.

    public class UnityControllerFactory : DefaultControllerFactory

    {

        protected override IController GetControllerInstance(RequestContext reqContext, Type controllerType)

        {

            IController controller;

            if (controllerType == null)

                throw new HttpException(

                        404, String.Format(

                            "The controller for path '{0}' could not be found" +

            "or it does not implement IController.",

                        reqContext.HttpContext.Request.Path));

     

            if (!typeof(IController).IsAssignableFrom(controllerType))

                throw new ArgumentException(

                        string.Format(

                            "Type requested is not a controller: {0}",

                            controllerType.Name),

                            "controllerType");

            try

            {

                controller = MvcUnityContainer.Container.Resolve(controllerType)

                                as IController;

            }

            catch (Exception ex)

            {

                throw new InvalidOperationException(String.Format(

                                        "Error resolving controller {0}",

                                        controllerType.Name), ex);

            }

            return controller;

        }

     

    }

     

    public static class MvcUnityContainer

    {

        public static IUnityContainer Container { get; set; }

    }

     

    Step 3 – Register Types and Set Controller Factory

    private void ConfigureUnity()

    {

        //Create UnityContainer          

        IUnityContainer container = new UnityContainer()

        .RegisterType<IFormsAuthentication, FormsAuthenticationService>()

        .RegisterType<IMembershipService, AccountMembershipService>()

        .RegisterInstance<MembershipProvider>(Membership.Provider)

        .RegisterType<IDinnerRepository, DinnerRepository>();

        //Set container for Controller Factory

        MvcUnityContainer.Container = container;

        //Set Controller Factory as UnityControllerFactory

        ControllerBuilder.Current.SetControllerFactory(

                            typeof(UnityControllerFactory));           

    }

    Unity 2.0 provides a fluent interface for type configuration. Now you can call all the methods in a single statement.The above Unity configuration specified in the ConfigureUnity method tells that, to inject instance of DinnerRepositiry when there is a request for IDinnerRepositiry and  inject instance of FormsAuthenticationService when there is a request for IFormsAuthentication and inject instance of AccountMembershipService when there is a request for IMembershipService. The AccountMembershipService class has a dependency with ASP.NET Membership provider. So we configure that inject the instance of Membership Provider.

    After the registering the types, we set UnityControllerFactory as the current controller factory.

    //Set container for Controller Factory

    MvcUnityContainer.Container = container;

    //Set Controller Factory as UnityControllerFactory

    ControllerBuilder.Current.SetControllerFactory(

                        typeof(UnityControllerFactory));


    When you register a type  by using the RegisterType method, the default behavior is for the container to use a transient lifetime manager. It creates a new instance of the registered, mapped, or requested type each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes.

    The following are the LifetimeManagers provided by Unity 2.0


    ContainerControlledLifetimeManager - Implements a singleton behavior for objects. The object is disposed of when you dispose of the container.

    ExternallyControlledLifetimeManager - Implements a singleton behavior but the container doesn't hold a reference to object which will be disposed of when out of scope.

    HierarchicalifetimeManager - Implements a singleton behavior for objects. However, child containers don't share instances with parents.

    PerResolveLifetimeManager - Implements a behavior similar to the transient lifetime manager except that instances are reused across build-ups of the object graph.

    PerThreadLifetimeManager - Implements a singleton behavior for objects but limited to the current thread.

    TransientLifetimeManager - Returns a new instance of the requested type for each call. (default behavior)

    We can also create custome lifetime manager for Unity container. The following code creating a custom lifetime manager to store container in the current HttpContext.

    public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable

    {

        public override object GetValue()

        {

            return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];

        }

        public override void RemoveValue()

        {

            HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);

        }

        public override void SetValue(object newValue)

        {

            HttpContext.Current.Items[typeof(T).AssemblyQualifiedName]

                = newValue;

        }

        public void Dispose()

        {

            RemoveValue();

        }

    }


     Step 4 – Modify Global.asax.cs for configure Unity container

     In the Application_Start event, we call the ConfigureUnity method for configuring the Unity container and set controller factory as UnityControllerFactory

    void Application_Start()

    {

        RegisterRoutes(RouteTable.Routes);

     

        ViewEngines.Engines.Clear();

        ViewEngines.Engines.Add(new MobileCapableWebFormViewEngine());

        ConfigureUnity();

    }



    Download Code

    You can download the modified NerdDinner code from http://nerddinneraddons.codeplex.com
  • Microsoft Unity 2.0 Released


    Microsoft's dependency injection framework Unity Application Block (Unity) has reached version 2.0. The release available on Codeplex at http://unity.codeplex.com/

    Unity 2.0 

     UnityContainer Fluent Interface

    Unity 2.0 provides a fluent interface for type configuration. Now you can call all the methods in a single statement, as shown in the following code.

     

    IUnityContainer container = new UnityContainer()

    .RegisterType<IFormsAuthentication, FormsAuthenticationService>()

    .RegisterType<IMembershipService, AccountMembershipService>()

    .RegisterInstance<MembershipProvider>(Membership.Provider)

    .RegisterType<IDinnerRepository, DinnerRepository>();  

     

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