Thursday 29 November 2012

Integrating Autofac with ASP.Net MVC 4. (25 min)



Integrating Autofac with ASP.Net MVC 4. (25 min)

Tools required: (minimum)
- Autofac .NET IoC container

This post is aimed to demonstrate an implementation of Autofac (IoC container) with ASP.NET MVC 4. As usual I will skip the theory since you can just Google it (how would be the world without google) and find a bunch of useful info about Dependency Injection (book here), Inversion of control and ASP.NET MVC 4.
1)  Open Visual Studio and create a new project, name it AutofacDemo

2)  From Installed Templates select Visual C# > ASP.NET MVC4 Web Application > Click OK and then select template: Basic (An basic ASP.NET MVC 4 project)


 


3)  Download Autofac binaries here (get release for .NET 4).

4)  Add the assemblies to the project.





5)  Add a class to the project and name it AutofacScopeContainer

6)  Replace the auto generated code for your class with the following:

using System;
using System.Collections.Generic;
using HttpDependencies = System.Web.Http.Dependencies;
using Autofac;
using AutofacMvc = Autofac.Integration.Mvc;

namespace AutofacDemo
{
    public class AutofacScopeContainer : HttpDependencies.IDependencyScope
    {
        protected AutofacMvc.AutofacDependencyResolver container;

        public AutofacScopeContainer(AutofacMvc.AutofacDependencyResolver container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            if (container.ApplicationContainer.IsRegistered(serviceType))
            {
                return this.container.GetService(serviceType);
            }
            else
            {
                return null;
            }
           
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (container.ApplicationContainer.IsRegistered(serviceType))
            {
                return this.container.GetServices(serviceType);
            }
            else
            {
                return new List<object>();
            }
        }

        public void Dispose()
        {
            container.ApplicationContainer.Dispose();
        }

    }

    public class AutoFacContainer : AutofacScopeContainer, HttpDependencies.IDependencyResolver
    {
        public AutoFacContainer(AutofacMvc.AutofacDependencyResolver container): base(container)
        {
        }

        public HttpDependencies.IDependencyScope BeginScope()
        {
            return this;
        }
    }
}


7)  Add another class and name it: Book and replace the auto generated code for your class with the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace AutofacDemo
{
    public class Book
    {
        public string ID { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
        public string Edition { get; set; }
        public string ISBN10 { get; set; }
    }
}

8)  Add an Interface and name it: IBookRepository and replace the auto generated code for your class with the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AutofacDemo
{
    public interface IBookRepository
    {
        Book Get();
    }
}


9)  Add a class to implement IBookRepository and name it: BookRepository and replace the auto generated code for your class with the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace AutofacDemo
{
    public class BookRepository : IBookRepository
    {
        public Book Get()
        {
            //
            // Implement your web service or your preferred ORM (EF/nhibernate/ mybatis.net...)
            //
            return new Book()
            {
                ID = "1",
                Author = "Unknown",
                Edition = "2012",
                ISBN10 = "978-0061122415 ",
                Title = "Autofac demo"
            };
        }

    }
}

10)Add a controller and name it BookController (Right click on Controllers folder>Add>Controller>Template: Empty MVC controller)


11)Replace the auto generated code for BookController with the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace AutofacDemo.Controllers
{
    public class BookController : Controller
    {

        private readonly IBookRepository _bookRepository;

        public BookController(IBookRepository bookRepository)
        {
            _bookRepository = bookRepository;
        }
        //
        // GET: /Book/

        public ActionResult Index()
        {
            //@model AutofacDemo.Book
            var book = _bookRepository.Get();

            // View Index.cshtml
            return View(book);
        }

    }
}


12)Press Ctrl+Shift+B (Build solution, we need it for the next step)

13)Right click on Index method and Select Add View > Select a strong-typed view > Model class: Book (AutofacDemo) >Scaffold template:Details>Click [Add] Button.

14)Open Global.asax (Global.asax.cs) and add the following method to MvcApplication class

void SetUpAutoFac(HttpConfiguration config)
{
var builder = new ContainerBuilder();
       builder.RegisterType<BookController>();
       builder.RegisterType<BookRepository>().As<IBookRepository>();
       var container = builder.Build();

       DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

       var resolver = new AutofacDependencyResolver(container);

       config.DependencyResolver = new AutoFacContainer(resolver);
}

15)Resolve assembly reference errors (Right click on the errors, select resolve and the right assembly)


16) Add at the end of method Application_Start() the following line of code

SetUpAutoFac(GlobalConfiguration.Configuration);

17)Open RouteConfig.cs located at App_Start and change the value “Home” for “Book” as seen in the next screen shot
18)Press F5. From here you can start enjoying the benefits of using Autofac container. Enjoy it!

Considerations
In the TDD world you would have first created a failing test here, and there, then some code to pass the test, refactor, and refactor again to finally have a decent code using your preferred coding best practices. Well known testing frameworks: MSTest, NUnit, xUnit.