Or, "How I prefer to build Umbraco" might also be a suitable title. Everyone builds Umbraco differently and there is no right or wrong way, whatever works for you. But I thought I would share my preferred way. There is nothing groundbreaking with this tutorial, it basically just a collection of other great tutorials that I think works great together with Umbraco using a TDD approach.

To not exclude anyone who's new to Umbraco I'll start from the very beginning on how to install Umbraco. If you're already familiar with these steps you can skip a few steps as we'll be going into more advance terms later on.

Please note that since posting this tutorial, Umbraco 8 has been released which contains a lot of breaking changes. This tutorial will most likely not work for Umbraco 8, so I have updated it to focus on how to install Umbraco 7.13.2 with Unit Testing, Dependency Injection, Custom Mappings and Route Hijacking. I might update it in the future to work with Umbraco 8.

Installing Umbraco 7.13.2

First create a new empty ASP.NET Web Application in Visual Studio. Then from NuGet Package Manager Console, run the following command:

PM> Install-Package UmbracoCms -v 7.13.2

That’s pretty much it. Run the command, go grab a cup of coffee and by the time you get back your Umbraco project will be installed.

The first time you run your site you’ll be promoted to answer a couple of questions about your environment and after that you are good to go. You’ll be asked if you want to start with an empty install or if you want to install a starter-kit. The starter-kit is great if you're new to Umbraco and just want to play around with it, but for a real client project I’d recommend starting with an empty install.

More on how to get started with Umbraco.

Create a project for your implementation code

Try to avoid mixing your implementation code with the Umbraco project. This is going to make a lot of things easier for you. It’s also the recommended approach when you’re installing Umbraco Cloud (which by the way is awesome!), so even if you're not intending to move the project to the clouds just yet, there's no harm in preparing for the day that you change your mind.

More on how to setup Umbraco Cloud in Visual Studio.

By ‘implementation code’ I mean all your controllers, models, interfaces, helpers, extensions, events, constants, attributes, you name it. Create a class library within the same solution and then reference that project in your Umbraco project and then you're all set.

Create a project for your tests

You should never mix your implementation code with your tests. Create another class library within your solution for your tests. Also you need some sort testing framework. In this example we'll be using NUnit by running this NuGet command:

PM> Install-Package NUnit

A big part of testing is mocking and for this you'll need a another framework:

PM> Install-Package Moq

Mocking Umbraco dependencies used to be a bit tricky, but not anymore thanks to this awesome package called Umbraco Context Mock. There is a few steps to take when installing this package and I’m not going to copy them all here, instead you should follow the tutorial on this page: https://skrift.io/articles/archive/unit-testing-umbraco-with-umbraco-context-mock/. Note: The rest of this article's code examples will assume that you've taken this tutorial.

Here is an example of how easy it is now to setup a mocked Umbraco Context using this package. Further down I'll include some actual tests using these mocks.

[SetUp] public void SetUp () { var mocker = new ContextMocker(); this .controller = new StandardPageController(mocker.UmbracoContextMock); }

Dependency Injection

Setting up Dependency Injection in Umbraco is super easy thanks to another awesome community project called Our.Umbraco.IoC. First install the package with your preferred IoC container, Autofac or LightInject. I prefer using Autofac:

PM> Install-Package Our.Umbraco.IoC.Autofac

After running the NuGet command you need to create a class that will be used for registering your services when the application is initialized.

public class AppBootstrapper : ApplicationEventHandler { protected override void ApplicationInitialized ( UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext ) { AutofacStartup.ContainerBuilding += (sender, args) => { args.Builder.RegisterControllers(Assembly.GetExecutingAssembly()); args.Builder.RegisterType<MyCustomService>().As<ICustomService>().InstancePerLifetimeScope(); }; } }

More on how to use IoC / Dependency Injection in Umbraco.

Custom Controller and View Models

Being the friendly CMS that Umbraco is, it also does a lot of magic for you behind the scenes. Umbraco will automagically route the current page request to a view template for you. Not only that but it will also map the current page to a generated class file, which contains the same properties as you have configured in the back-office, using a built in tool called ModelsBuilder. This means that you can actually create a new page type, map it to a view model and render it in a view without writing a single line of server-side code. This is truly impressive and especially great if you’re new to Umbraco and you just want to get started quickly.

However, I prefer to disable ModelsBuilder and build my view models myself. In my web.config, I set ModelsBuilder.Enable to false.

<add key= "Umbraco.ModelsBuilder.Enable" value = "false" />

I build my view models using a package called UmbracoMapper.

PM> Install-Package UmbracoMapper

Then I register UmbracoMapper in my bootstrapper to be able to inject it in my controllers.

args.Builder.RegisterType<UmbracoMapper>().As<IUmbracoMapper>().InstancePerLifetimeScope();

More on how to configure UmbracoMapper.

I also prefer to route my views using my own controllers by implementing something called Route Hijacking. This is done by having my controllers inheriting a class called RenderMvcController, which is like saying -“Thanks Umbraco, I’ll take it from here!”. There is no package needed to enable Route Hijacking, but it might be a good idea to read up on it if your new to the concept.

More about Route Hijacking in Umbraco.

What I like to do is create a base controller for all my page controllers, that inherits RenderMvcController and takes in a generic view model, and then maps the current requested content to that view model using UmbracoMapper and then returns that view model to my view. So pretty much what Umbraco does for you out of the box, except now I have full control over what's gets populated, how it got there and how to test it. Here is my base controller, building on code from the testing tutorial.

public abstract class BasePageController<TModel> : BaseRenderMvcController where TModel : class , new () { private readonly IUmbracoMapper umbracoMapper; protected BasePageController(UmbracoContext umbracoContext, IUmbracoMapper umbracoMapper) : base(umbracoContext) { this .umbracoMapper = umbracoMapper; } public override ActionResult Index(RenderModel model) { return View( this .MapModel(model.Content)); } public virtual TModel MapModel(IPublishedContent content) { var model = new TModel(); this .umbracoMapper.Map(content, model); return model; } }

Now all my page controllers inherits this base controller and I just need to pass in the view model i want to map to and the rest will be taken care of for me. So an example of how a StandardPageController could look like:

public class StandardPageController : BasePageController < StandardPageViewModel > { public StandardPageController ( UmbracoContext umbracoContext, IUmbracoMapper umbracoMapper) : base(umbracoContext, umbracoMapper) {} public override ActionResult Index ( RenderModel model) { return base. Index (model); } }

Clean isn’t it? It gets better. Here’s is an example of how this could look using unit tests with the test setup I mentioned earlier:

[TestFixture] public class StandardPageControllerTests { private StandardPageController controller; private Mock<IPublishedContent> content; [SetUp] public void SetUp () { this .content = new Mock<IPublishedContent>(); this .controller = new StandardPageController( new ContextMocker().UmbracoContextMock, new UmbracoMapper()); } [Test] [TestCase( "" , null )] [TestCase( null , null )] [TestCase( "My Heading" , "My Heading" )] [TestCase( "Another Heading" , "Another Heading" )] public void GivenContentHasHeading_WhenIndexAction_ThenReturnViewModelWithHeading ( string heading, string expected ) { SetupPropertyValue( "heading" , heading); var viewModel = (StandardPageViewModel)((ViewResult) this .controller.Index( new RenderModel(content.Object, CultureInfo.CurrentCulture))).Model; Assert.AreEqual(expected, viewModel.Heading); } [Test] [TestCase( "" , null )] [TestCase( null , null )] [TestCase( "My Subheading" , "My Subheading" )] [TestCase( "Another Subheading" , "Another Subheading" )] public void GivenContentHasSubHeading_WhenIndexAction_ThenReturnViewModelWithSubHeading ( string subHeading, string expected ) { SetupPropertyValue( "subHeading" , subHeading); var viewModel = (StandardPageViewModel)((ViewResult) this .controller.Index( new RenderModel(content.Object, CultureInfo.CurrentCulture))).Model; Assert.AreEqual(expected, viewModel.SubHeading); } public void SetupPropertyValue ( string propertyAlias, object value , bool recursive = false ) { var property = new Mock<IPublishedProperty>(); property.Setup(x => x.PropertyTypeAlias).Returns(propertyAlias); property.Setup(x => x.Value).Returns( value ); content.Setup(x => x.GetProperty(propertyAlias, recursive)).Returns(property.Object); } }

Wrapping up

As mentioned, everyone builds Umbraco differently and there is no right or wrong way. This is my preferred way and you are welcome to pick and choose the pieces you prefer and ignore the once you don't. As long as you choose Umbraco for your next project I’ll be happy! :)

Merry Christmas and a Happy New Year. And take care of each other.