Introducing Windsor Dependency Injection container into Umbraco application.

IoC

When I first saw the Dependency Injection pattern used in a source code, I did not understand what I was looking at. For a beginner, it just seemed as an unnecessary complication made be some senior developer, to make my life even harder. Passing some objects into the service just to call their methods. Making a complicated constructor to pass 15 other dependencies. But I was young and some time had to pass before I had the aha moment and finally understood what it is all about.
After that, it all made perfect sense. Instead of creating lot of nested code, that is tightly coupled, with static method, you just pass required dependencies into the object. With that, you can create the code in the way that will allow you to focus of writing and testing only one functionality at a time. You can easily mock other dependencies that are not relevant at the moment. It introduces a clarity in the code.

Umbraco and IoC

Umbraco documentation states as following:

We don’t use IoC in the Umbraco source code. This isn’t because we don’t like it or don’t want to use it, it’s because we want you as a developer to be able to use whatever IoC framework that you would like to use without jumping through any hoops.
With that said, it means it is possible to implement whatever IoC engine that you’d like!

With that in mind, I would like to show you how to add the Windsor Dependency Injection container into an Umbraco web application as an example.

Adding IoC into Umbraco

First step to add Windsor Container is to create class that extends UmbracoApplication class. This gives as ability to override method OnApplicationStarted. In this method we can replace both default MVC and WebApi Dependency Resolvers.

1
2
3
4
5
6
7
8
protected override void OnApplicationStarted(object sender, EventArgs e)
{

base.OnApplicationStarted(sender, e);

var resolver = new WindsorDependencyResolver(_container.Value, DependencyResolver.Current);
DependencyResolver.SetResolver(resolver);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}

Second thing to do is replacing default UmbracoApplication in Global.asax file:

1
<%@ Application Inherits="UmbracoDemo.DemoApplication" Language="C#" %>

WindsorDependencyResolver is adapter class that allows us to use Windsor as dependency container in MVC application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class WindsorDependencyResolver :
System.Web.Mvc.IDependencyResolver,
System.Web.Http.Dependencies.IDependencyResolver
{
private readonly IWindsorContainer _container;
private readonly System.Web.Mvc.IDependencyResolver _mvcDependencyResolver;
private readonly IDependencyResolver _webApiDependencyResolver;

private readonly IDependencyScope _lifeTimeScope;

public WindsorDependencyResolver(
IWindsorContainer container,
System.Web.Mvc.IDependencyResolver mvcDependencyResolver,
System.Web.Http.Dependencies.IDependencyResolver webApiDependencyResolver)
{
_container = container;
_mvcDependencyResolver = mvcDependencyResolver;
_webApiDependencyResolver = webApiDependencyResolver;

_lifeTimeScope = new WindsorWebApiDependencyScope(
_container,
_mvcDependencyResolver,
_webApiDependencyResolver);
}

public object GetService(Type serviceType)
{
return _lifeTimeScope.GetService(serviceType);
}

public IEnumerable<object> GetServices(Type serviceType)
{
return _lifeTimeScope.GetServices(serviceType);
}

public System.Web.Http.Dependencies.IDependencyScope BeginScope()
{
return new WindsorWebApiDependencyScope(_container,
_mvcDependencyResolver,
_webApiDependencyResolver);
}

public void Dispose()
{
}
}

Constructor in WindsorDependencyResolver takes three parameters, first is the Windsor container, second one is the default MVC Dependency Resolver and the third is the default WebApi Dependency Resolver. The latter is used to first check if the service is not registered there.

The BeginScope method returns adapter class of Windsor container for WebAPI IDependencyScope. It allows to restrict service lifetime to a scope. It can be useful for situation when you don’t want to create singletons and also you don’t want service to be created every time it is being referenced. For example, we can create a scope for a http request and allow all methods/classes to use same instances during one request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class WindsorWebApiDependencyScope :
System.Web.Http.Dependencies.IDependencyScope
{
private readonly IWindsorContainer _windsorContainer;

private readonly System.Web.Mvc.IDependencyResolver _mvcDependencyResolver;
private readonly IDependencyResolver _webApiDependencyResolver;
private readonly IDisposable _disposable;


public WindsorWebApiDependencyScope(
IWindsorContainer container,
System.Web.Mvc.IDependencyResolver mvcDependencyResolver,
System.Web.Http.Dependencies.IDependencyResolver webApiDependencyResolver)
{
_mvcDependencyResolver = mvcDependencyResolver;
_webApiDependencyResolver = webApiDependencyResolver;
_windsorContainer = container;

_disposable = _windsorContainer.BeginScope();
}

public object GetService(Type serviceType)
{
try
{
var serviceFromWindsor = _windsorContainer.Resolve(serviceType);
if (serviceFromWindsor != null)
return serviceFromWindsor;
}
catch (Exception) { /* ignored */ }

try
{
var serviceFromMvc = _mvcDependencyResolver.GetService(serviceType);
if (serviceFromMvc != null)
return serviceFromMvc;
}
catch (Exception) { /*ignored*/ }

try
{
var serviceFromWebApi = _webApiDependencyResolver.GetService(serviceType);
if (serviceFromWebApi != null)
return serviceFromWebApi;
}
catch (Exception) { /* ignored */ }

return null;
}

public IEnumerable<object> GetServices(Type serviceType)
{
try
{
var servicesFromWindsor = _windsorContainer.ResolveAll(serviceType)
.Cast<object>();
if (servicesFromWindsor != null && servicesFromWindsor.Any())
return servicesFromWindsor;
}
catch (Exception) { /* ignored */ }

try
{
var currentServiceList = _mvcDependencyResolver.GetServices(serviceType);
if (currentServiceList != null && currentServiceList.Any())
return currentServiceList;
}
catch (Exception) { /* ignored */ }

try
{
var webApiServices = _webApiDependencyResolver.GetServices(serviceType);
if (webApiServices != null && webApiServices.Any())
return webApiServices;
}
catch (Exception) { /* ignored */ }


return Enumerable.Empty<object>();
}

public void Dispose()
{
_disposable.Dispose();
}
}

As you can see above, ther order of services lookup is as following :

  • Windsor Container
  • Default Mvc Dependency Resolver
  • Default WebAPI Dependency Resolver.

Register Controllers

Registering custom controllers looks like this:

1
2
3
4
5
6
7
8
9

private static void RegisterStandardClasses(WindsorContainer container)
{

// Register all controllers from current assembly
RegisterFromAssembly<DemoApplication, ApiController>(container);
RegisterFromAssembly<DemoApplication, Controller>(container);
RegisterFromAssembly<DemoApplication, SurfaceController>(container);
RegisterFromAssembly<DemoApplication, RenderMvcController>(container);
}

RegisterFromAssembly method is a static method that I’ve created to easily add controllers.

1
2
3
4
5
6
7
private static void RegisterFromAssembly<TAssemblyClass, TService>(IWindsorContainer container)
{
container
.Register(Classes.FromAssemblyContaining<TAssemblyClass>()
.BasedOn<TService>()
.LifestyleTransient());
}

Using Umbraco services interfaces

To register custom services you must call the Register method on the container. The Component class is a static class that serves as a Factory class and allows to connect interface with it’s concrete implementation. Also we need can define the lifetime of the registered class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static IWindsorContainer Initialize()
{

var container = new WindsorContainer();

RegisterStandardClasses(container);

container.Register(Component
.For<IEmailService>()
.ImplementedBy<EmailService>()
.LifestyleSingleton());

container.Register(Component
.For<ICityRepository>()
.ImplementedBy<CityRepository>()
.LifestyleSingleton());

return container;
}

Using custom services

To use custom services in your controllers and filters you just need to pass it into the constructor of the controller/filter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ExampleController : SurfaceController
{
private readonly IContentService _contentService;
private readonly ICityRepository _cityRepository;

public ExampleController(
IContentService contentService,
ICityRepository cityRepository)

{

_contentService = contentService;
_cityRepository = cityRepository;
}

// GET: Example
public ActionResult Index()
{

var rootContent = _contentService.GetRootContent();
ViewBag.Cities = _cityRepository.GetCities();

return View(rootContent);
}
}

That would be it. Thanks for reading :)

Setting correct culture in AJAX request to Umbraco SurfaceController

Problem

Project that I’m working on contains a form that is being validated.
My latest task was to add remote validation for the password field to check it against existing server code.
I’ve described this in my previous post.

There was one problem which I did not described in that post.
This site has multiple languages and we are using Umbraco dictionary to manage translations for texts on our page.
One of those texts are validation messages for form.

Key to this dictionary item is set via attribute that is marking property.

1
2
3
4
5
[UmbracoDisplayName("MyProject.Form.Password")]
[UmbracoRequired(ErrorMessageDictionaryKey = "MyProject.Form.Required")]
[DataType(DataType.Password)]
[Remote("ValidatePassword", "Validation", HttpMethod = "POST", AdditionalFields = "EmailAddress")]
public string Password { get; set; }

The MyProject.Form.Password is an entry in Umbraco dictionary that was translated into couple of languages.

It worked great with server side validation. After form was submitted, whole Umbraco page was send to server. Server had full context for a page.
Proper culture was correctly set based on the Umbraco page context. So validation message was displayed in proper language.

Problem appeared when I’ve started to use the RemoteAttribute.
This way I was calling server validation method with an AJAX request. In this situation, Umbraco could not correctly read the language from the request.

The method I found in the existing solution was to get current culture from the url and mapping in Umbraco.

Following algorithm was used to detect current culture.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public class UmbracoService : IUmbracoService
{
private readonly IDomainService _domainService;

public UmbracoService(IDomainService domainService)
{

_domainService = domainService;
}

// TODO : poor man ioc
public UmbracoService()
: this(UmbracoContext.Current.Application.Services.DomainService)
{ }


protected HttpRequest Request => HttpContext.Current.Request;

public string GetCultureCode()
{

//Get language id from the Root Node ID
string requestDomain = Request.ServerVariables["SERVER_NAME"].ToLower();

var domain = GetMatchedDomain(requestDomain);

if (domain != null)
{
return domain.LanguageIsoCode;
}

return "en-US";
}

protected string NormalizeUrl(string originalUrl)
{

return originalUrl
.Replace("https://", string.Empty)
.Replace("http://", string.Empty);
}

/// <summary>
/// Gets domain object from request. Errors if no domain is found.
/// </summary>
/// <param name="requestDomain"></param>
/// <returns></returns>
public IDomain GetMatchedDomain(string requestDomain)
{

var domainList = _domainService
.GetAll(true)
.ToList();

string fullRequest = Request.Url.AbsolutePath.ToLower().Contains("/umbraco/surface")
? NormalizeUrl(Request.UrlReferrer.AbsoluteUri)
: requestDomain + Request.Url.AbsolutePath;

// walk backwards on full Request until domain found
string currentTest = fullRequest;
IDomain matchedDomain = null;
while (currentTest.Contains("/"))
{
matchedDomain = domainList
.SingleOrDefault(x => x.DomainName == currentTest.TrimEnd('/'));
if (matchedDomain != null)
{
// this is the actual domain
break;
}
if (currentTest == requestDomain)
{
// no more to test.
break;
}

currentTest = currentTest.Substring(0, currentTest.LastIndexOf("/"));
matchedDomain = domainList
.SingleOrDefault(x => x.DomainName == currentTest);
if (matchedDomain != null)
{
// this is the actual domain
break;
}
}

return matchedDomain;
}
}

To test it I’ve created the view. When the page is viewed in English language, both fields display message in English language.
But when I switch to Polish language demo.umbraco.com/pl, then first message is displayed in English and the second one in Polish.

I hope that helped you. :)

You can find working version of this code in my github repo.

Validating ASP.NET MVC form in razor with AJAX using RemoteAttribute in Umbraco application

Challenge

My task was to add client side validation of password field to existing form.
Validation on server side was already implemented.
Rewriting the password validation algorithm on client doesn’t made sense.
Only question was how to reuse this logic.

I’ve used the jQuery Unobtrusive Validation library provided for ASP.NET MVC.
MVC comes with System.Web.Mvc.RemoteAttribute class.
This class needs to be put on property that you want to remotely validate.

1
2
3
4
5
6
7
[Required]
[Remote("ValidatePassword",
"Validation",
HttpMethod = "POST",
AdditionalFields = "EmailAddress, UserName")]
[DataType(DataType.Password)]
public string Password { get; set; }

The RemoteAttribute has couple of parameters to pass :

  • ValidatePassword - name of an action inside a ASP.NET MVC Controller that will be used to validate,
  • Validation - name prefix of controller (full name: ValidationController), that contains validation action,
  • HttpMethod = "POST" - http method used to communicate with server, with POST method, password will not be exposed in url,
  • AdditionalFields = "EmailAddress, UserName" - fields that we want to send along with the password to validation action.

ValidationController class :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public class ValidationController : SurfaceController
{
[System.Web.Http.HttpPost]
public JsonResult ValidatePassword(ValidatePasswordRequest request)
{

if (string.IsNullOrWhiteSpace(request.EmailAddress)
|| string.IsNullOrWhiteSpace(request.UserName)
|| string.IsNullOrWhiteSpace(request.Password))
{
return Json(true);
}

var validationResults = PasswordValidator.Validate(
request.Password,
request.UserName,
request.EmailAddress);

// if no errors were returned then return true
if (validationResults == PasswordMessage.Valid)
return Json(true);

return Json(validationResults.ToString());
}
}

ValidatePassword action method is marked with HttpPost attribute.
This will tell the server to only accept http POST requests.

Method takes as a parameter object of following class:

1
2
3
4
5
6
public class ValidatePasswordRequest
{
public string Password { get; set; }
public string UserName { get; set; }
public string EmailAddress { get; set; }
}

Name of properties in the ValidatePasswordRequest class must match names of view model that is used to render the form.

Following class is being used to render form:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class RegisterUserViewModel
{
[DisplayName("User name")]
[Required]
public string UserName { get; set; }

[DisplayName("Email address")]
[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress]
public string EmailAddress { get; set; }

[Required]
[Remote("ValidatePassword",
"Validation",
HttpMethod = "POST",
AdditionalFields = "EmailAddress, UserName")]
[DataType(DataType.Password)]
public string Password { get; set; }

[DisplayName("Password confirmation")]
[Required]
[DataType(DataType.Password)]
public string PasswordConfirmation { get; set; }
}

In razor we have just a standard form:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@using (Html.BeginUmbracoForm<RegisterUserController>(
"MemberRegister", FormMethod.Post, new { @class = "validate-form" }))
{
...

<fieldset class="form-group">
<label>
@Html.DisplayNameFor(m => m.Password) <sup>*</sup>
</label>
@Html.EditorFor(m => m.Password,
new { htmlAttributes = new { @class = "form-control" }})
@Html.ValidationMessageFor(m => m.Password,
string.Empty, new { @class = "error" })
</fieldset>

...
}

We need to also turn on the jQuery unobtrusive validation in web.config:

1
2
3
4
5
6
<configuration>
...
<appSettings>
...
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

Additionaly we need to include following scripts in our page, at the end of html body element:

1
2
3
4
5
6
7
    ...
<!-- Javascripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.15.0/jquery.validate.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/5.2.3/jquery.validate.unobtrusive.js"></script>
</body>
</html>

Full working code can be found on a branch of my Umbraco sandbox repo.

Rendering Asp.Net Mvc form fields with Razor @helper function and HtmlHelper extension method

Problem

When you write any kind of form on your page, you often end up with source like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@using UmbracoTest.Controllers
@inherits UmbracoViewPage<UmbracoTest.ViewModels.MemberRegisterModel>

@{
ViewBag.Title = "Membership Registration Before refactor";
}

<h2>Membership Registration</h2>

@using (Html.BeginUmbracoForm<MembershipController>(
"MemberRegister",
FormMethod.Post,
new { @class = "validate-form" }))
{
<fieldset class="form-group">
<label>
@Html.DisplayNameFor(m => m.GivenNames)
</label>
@Html.EditorFor(m => m.GivenNames,
new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(m => m.GivenNames,
string.Empty, new { @class = "error" })
</fieldset>

<fieldset class="form-group">
<label>
@Html.DisplayNameFor(m => m.FamilyNames) <sup>*</sup>
</label>
@Html.EditorFor(m => m.FamilyNames,
new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(m => m.FamilyNames,
string.Empty, new { @class = "error" })
</fieldset>

<fieldset class="form-group">
<label>
@Html.DisplayNameFor(m => m.EmailAddress) <sup>*</sup>
</label>
@Html.EditorFor(m => m.EmailAddress,
new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(m => m.EmailAddress,
string.Empty, new { @class = "error" })
</fieldset>

<fieldset class="form-group">
<label>
@Html.DisplayNameFor(m => m.EmailAddressConfirmation) <sup>*</sup>
</label>
@Html.EditorFor(m => m.EmailAddressConfirmation,
new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(m => m.EmailAddressConfirmation,
string.Empty, new { @class = "error" })
</fieldset>
}

As we can see, the code repeats itself. The code in <label> element is almost the same for all fields in this form.

1
2
3
4
5
6
7
8
9
 <fieldset class="form-group">
<label>
@Html.DisplayNameFor(m => m.FamilyNames) <sup>*</sup>
</label>
@Html.EditorFor(m => m.FamilyNames,
new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(m => m.FamilyNames,
string.Empty, new { @class = "error" })
</fieldset>

This is code smell because in the name of DRY rule, we should avoid code repeatition.

Only difference is the name of the field that we want to render. This name is taken from the expression passed to each of the functions:

  • @Html.DisplayNameFor
  • @Html.EditorFor
  • @Html.ValidationMessageFor

Additionaly, the * sign in most of the fileds is added manually.
This is code smell, because we have this information already in the model.

This view has a view model that is connected to it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 public class MemberRegisterModel : RenderModel, IValidatableObject
{
public MemberRegisterModel()
: base(UmbracoContext.Current.PublishedContentRequest.PublishedContent)
{ }

[DisplayName("First Name")]
public virtual string GivenNames { get; set; }

[DisplayName("Last Name")]
[Required]
public virtual string FamilyNames { get; set; }

[DisplayName("Email")]
[Required]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }

[DisplayName("Email Confirmation")]
[Required]
[DataType(DataType.EmailAddress)]
public string EmailAddressConfirmation { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
throw new System.NotImplementedException();
}
}

Solution

The RequiredAttribute is telling the validator that this property is required.
We could use that information to automatically render the required indicator -> *.

To check if property should be marked with * we need to check if the propert has the RequiredAttribute.
Below code checks if given property has a attribute of type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace UmbracoTest.Helpers
{
public static class PropertyExpressionExtensions
{
public static bool HasAttribute<TModel, TPropertyType, TAttribute>(
this Expression<Func<TModel, TPropertyType>> propertyExpression,
Func<TAttribute, bool> attributePredicate = null)
where TAttribute : Attribute
{
var expressionText = ExpressionHelper.GetExpressionText(propertyExpression);
var type = typeof(TModel);
var property = type.GetProperty(expressionText);

var attributeType = typeof(TAttribute);

var attributes = (TAttribute[])property.GetCustomAttributes(attributeType, true);

if (attributes.Any() == false)
return false;

if (attributePredicate != null && attributes.Any(attributePredicate) == false)
return false;

return true;
}
}
}

Here is the code for checking if property is marked with RequiredAttribute :

1
2
3
4
5
6
7
public static bool IsFieldRequired<TModel, TPropertyType>(
this Expression<Func<TModel, TPropertyType>> propertyExpression)
{
var hasRequiredAttribute =
propertyExpression.HasAttribute<TModel, TPropertyType, RequiredAttribute>();
return hasRequiredAttribute;
}

Shared template that is used to render field in Razor friendly way. This helper is stored in App_Code folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@using System.Web.Mvc.Html

@helper RenderFormFieldHelper(
System.Web.Mvc.HtmlHelper htmlHelper,
string fieldName,
bool isRequired)
{
<fieldset class="form-group">
<label>
@htmlHelper.DisplayName(fieldName)
@if (isRequired)
{
<sup>*</sup>
}
</label>
@htmlHelper.Editor(fieldName, new { htmlAttributes = new { @class = "form-control" } })
@htmlHelper.ValidationMessage(fieldName, string.Empty, new { @class = "error" })
</fieldset>
}

Following code is a litlle bit tricky.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static class HtmlHelperExtensions
{
public static HelperResult FormFieldFor<TModel, TResult>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TResult>> expression,
Func<HtmlHelper, string, bool, HelperResult> template)
where TModel : class
{
var isRequired = expression.IsFieldRequired();
var propertyName = ExpressionHelper.GetExpressionText(expression);

var result = template(html, propertyName, isRequired);
return result;
}
}

It’s extension to HtmlHelper class. Parameters passed to this method are folowing:

  • this HtmlHelper<TModel> html - this is the HtmlHelper, available in cshtml files,
  • Expression<Func<TModel, TResult>> expression - for strongly typed models, a better way to pass a property name,
  • Func<HtmlHelper, string, bool, HelperResult> template - @helper method that will be used to generate html result

ExpressionHelper.GetExpressionText(expression) - is a method provided by ASP.NET to get the name of the property from an expression.

Working code can be found on the branch of my umbraco sandbox repository.