Umbraco Web Api and MVC Dependency Injection configuration in mixed mode using Autofac

Introduction
In this article, I am going to present a complete tutorial how easily setup Dependency Injection using Autofac container in Umbraco solution. Once configured, we should be able to use DI in both MVC and Web API controllers. In many cases our website should be able to integrate with other services – in some cases, we need to create REST endpoint to feed some data. This can be done in a very easy way using Umbraco.Web.WebApi.UmbracoApiController. This class wraps classic WebApi engine – it’s possible to use Umbraco related objects and services. Our plan is to use benefits of Dependency Injection in sample controllers.

Solution set up
At the beginning, we should follow these steps:
– Create .NET solution with empty .NET ASP project
– Install Umbraco CMS from NuGet repository

Next, go to Nuget package Manager repository and install Autofac library with dependencies:
– Autofac.MVC5
– Autofac.WebApi2

Umbraco DI nuget autofac required packages

After the process finishes, we are ready to use Autofac and set up the container – Umbraco application started event is the right place. RegisterIoCContainer() method wraps the logic of building the container.

IOC set up

    protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {            
            RegisterIoCContainer();
        }
   private void RegisterIoCContainer()
        {
            var builder = new ContainerBuilder();

            /* MVC Controllers */
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
            builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
            builder.RegisterModelBinderProvider();

            /* WebApi Controllers */
            builder.RegisterApiControllers(typeof(UmbracoApplication).Assembly);
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            builder.RegisterModule<WebModule>();

            var container = builder.Build();

            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }

WebModule is a custom class which is used to bundle up a set of related components into one logical unit – it’s flexible and recommended approach. In this case, we have only two components SampleService and UmbracoContext – but you can register as many as you want. Thanks to the last line, UmbracoContext.Current is available through Dependency Injection.

public class WebModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<SampleService>()
                .As<ISampleService>();

            builder.Register(c => UmbracoContext.Current).AsSelf();
        }
    }

Data feed
For this purpose let’s create sample service with one method GetItems() returning some dummy data. We wanna use this data in both RenderMVCController and UmbracoApiController

public class SampleService : ISampleService
    {
        public IList<string> GetItems()
        {
            return new List<string>()
            {
                "Autofac",
                "Ninject",
                "Unity",
                "Castle Windsor",
                "Spring.NET",
                "StructureMap"
            };
        }
    }

Controllers and view

 public class SampleWebApiController : UmbracoApiController
    {
        private readonly ISampleService _sampleService;

        public SampleWebApiController(ISampleService sampleService)
        {
            _sampleService = sampleService;
        }
       
        [System.Web.Http.HttpGet]
        public JsonResult Get()
        {
            return new JsonResult() { Data = new { items = _sampleService.GetItems() }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }
    }

To create a view and show data from our ViewModel, we need to create document type, whose name corresponds to the name of the controller rendering the view. So let’s go to the backoffice and create a document type named “SampleRenderMvc” with a template. Then let’s create a custom class in “Controllers” folder named “SampleRenderMvcController”. After injecting ISampleService into local variable via constructor we are able to use ISampleService contract.

 public class SampleRenderMvcController : RenderMvcController
    {
        private readonly ISampleService _sampleService;

        public SampleRenderMvcController(ISampleService sampleService)
        {
            _sampleService = sampleService;
        }

        public ActionResult Index(RenderModel model)
        {
            return CurrentTemplate(new ExtendedModel(model.Content) { Items = _sampleService.GetItems() });
        }
    }

SampleRenderMvcController is ready, so let’s create a simple view based on ExtendedModel with items property.
Go to Views folder and change view type from UmbracoTemplatePage to UmbracoViewPage. With UmbracoViewPage view, it is possible to iterate via custom model property and render the list.

@inherits Umbraco.Web.Mvc.UmbracoViewPage<UmbracoCMSDIMixedMode.Web.Controllers.RenderMvc.ExtendedModel>
@{
    Layout = null;
}

<p>Popular IoC list:</p>
<ul>
    @foreach (var item in Model.Items)
    {
        <li>@item</li>
    }
</ul>

Manual testing
Checking api request is simple, I decided to use popular rest api client – Fiddler:
umbraco di result webapi view

To see if our mvc view properly displays service data, just enter the path of the content node into the browser – in my case it’s the root folder:

umbraco di result mvc view

Complete solution is avaliable on GitGub

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *