Umbraco and Dependency Injection. How it works!

Umbraco and Dependency Injection. How it works!

  • 10/09/2021
  • Basics
  • Umbraco 8

Since Umbraco launched their version 8 it can handle dependency injection, out of the box. Umbraco headquarter also encourages you to use dependency injection whenever it is possible and spoiler: its almost always possible!

"But how do I use dependency injection in Umbraco?"

Nice question! Let me answer it for you.

Let's image following scenario:

You want to show a navigation on the top of your page, to do that you will call you NavigationController with its LoadNavigation function in your template like that


@Html.Action("Navigation", "LoadNavigation")
                                

To handle all the logic of creating the navigation you will also have created a NavigationService which implements the interface INavigationService, it will look something like that


public interface INavigationService
{
    NavigationModel GetNavigation();
}

public class NavigationService : INavigationService
{
    public NavigationModel GetNavigation()
    {

    }
}
                                

As we want to use dependency injection we will inject our INavigationService into our Controller by using constructor injection


public class NavigationController : SurfaceController
{
    private readonly INavigationService _service;


    public NavigationController(INavigationService service)
    {
        _service = service;
    }

    public ActionResult LoadNavigation()
    {
        NavigationModel model = _service.GetNavigation();
        return View(model);
    }
}
                                

"But wait that doesn't work! I get an "System.InvalidOperationException: Unable to resolve type: ...." error!"

Thats true. The problem is we didn't tell Umbraco which implementation to use for our INavigationService.

For Umbraco to know which implementation to use we have to tell it within an IUserComposer.


public class RegisterDependenciesComposer : IUserComposer
{
    public void Compose(Composition composition)
    {
        composition.Register<INavigationService, NavigationService>(Lifetime.Scoped);
        //composition.Register<Interface, Implementation>(Lifetime);
    }
}
                                

In the composition we can register our own dependencies, with their own lifetimes. For the lifetime we can choose between three different types - Singleton, Scoped and Transient.

Quickly explained the differences are the following:

  • Singleton get initialized once per application so you will have the same implementation for all requests
  • Scoped will get initialized new for each request, so during a request you will always have the same implementation
  • Transient will create a new implementation each time they are requested

If you try now everything will work just as you would expect it! And thats it, dependency injection in Umbraco is that easy.

"Wow, cool. But isn't it a tedious work to always register them manually? Especially in large projects with dozens of services and repos? I am sure I will forget that more often than not and will get annoyed by the following errors!?" Thats exactly how i feel about it! Or rather how i felt about it! Thats why i created a package to make my life, and hopefully yours aswell, easier.

But more about that the next time!

If you have any questions, feel free to contact me