Thursday, 31 December 2015

Working with View Models in Umbraco and EPiServer

Cross-posting an article I've written for my company Zone's Medium blog. I've written about techniques for using strongly typed view models with Umbraco here before - in this article I recap some of that and extend the discussion to EPiServer CMS too.

You can read and comment on the article here.

Friday, 9 October 2015

ASP.Net 5 and C# 6: Slides and Resources

ASP.Net 5 and C# 6: Slides and Resources

Had the pleasure of speaking yesterday at the London Umbraco meet-up hosted at Zone on the topic of ASP.Net 5 and C# 6. For anyone who was there and wants a reference, or who wasn't and is interested in an introduction to this area, I'll post a few resources.

Firstly the slides from the talk are available here.

And then here's a number of links to blogs and other online resources that I've used in researching the topic and preparing the talk:

You can even watch it if you like.

Thanks to Ali, Ravi for organisation last night and all the attendees.

Saturday, 26 September 2015

DDD, CQRS and testing with ASP.Net MVC: Slides and References

Just had the pleasure of attending and speaking at the Web European Conference in Milan.

For anyone that attended my talk, or any that didn't but were tempted more by another session, here's some links to slides and references.

Slides can be found here at slideshare.net

And here's a few links to blog posts I've written before on the subject:

A few references to sources I used in researching and constructing the presentation:

Finally just to say a big thanks to all attendees, the organisers and sponsors. Hope to be back next year.

Sunday, 23 August 2015

Code As Data With Reflection

Other than occasional use, working with reflection using C# isn't something I've had that much need to do. Recently though I was working on an additional feature for the Umbraco package The Dashboard. It provides a nice first screen for editors, showing their recent edits and other work carried out on the site content.

The idea for the new feature was to create a developer version of this, that displayed various details about the code that had been implemented on the project. The use case being in the case of inheriting or coming back to a site, being able to have a quick overview of the techniques that have been used for route hijacking, surface controllers, application events and the like.

In order to implement this it was going to be necessary to make quite heavy use of reflection and this post highlights a few of the methods used.

Getting instances of types

In the case of Umbraco route hijacking using custom controllers it's necessary to implement an MVC controller that implements an interface (IRenderMvcController). Similarly for surface controllers, you need to inherit from a base class (SurfaceController). So to find all the instances of these I needed to search all the assemblies of the project and find all non-abstract, classes that implemented a given interface or inherited a given base type. I also wanted to exclude anything that came with the Umbraco core itself as that wasn't useful to display.

Here's the code I used:

public class ControllerDetailDto
{
    public string Name { get; set; }

    public string Namespace { get; set; }
}

public IEnumerable<ControllerDetailDto> GetControllersAssignableFrom(Type baseType)
{
    return GetNonCoreTypesAssignableFrom(baseType)
        .Select(x => new ControllerDetailDto
        {
            Name = x.Name,
            Namespace = x.Namespace,
        });
}

private IEnumerable<Type> GetNonCoreTypesAssignableFrom(Type baseType)
{
    return AppDomain.CurrentDomain.GetAssemblies()
        .SelectMany(s => s.GetTypes())
        .Where(p => baseType.IsAssignableFrom(p) && p.IsClass && !p.IsAbstract && !p.Namespace.ToLower().StartsWith("umbraco."));
}

Getting method details

In the case of custom controllers used for route hijacking, I also wanted to get the list of action methods. This was done by finding all public, non-static methods direct declared on the controller and filtering by those that returned ActionResult or something inheriting from it. I was only interested in the GET ones so obtained all those by excluding any that had an [HttpPost] attribute.

The crucial part of the code for doing this was as follows:

public IEnumerable<string> GetActionMethodsOnController(Type controllerType)
{
    return controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
        .Where(x => typeof (ActionResult).IsAssignableFrom(x.ReturnType) &&
            !x.Name.StartsWith("get_") &&
            (!x.GetCustomAttributes(typeof (HttpPostAttribute), false).Any()))
        .Select(x => x.Name)
        .OrderBy(x => x);
}

Getting event details

The last task I had was to get details of the application event handlers that had been registered. For a given Umbraco service, e.g. ContentService, there are a number of methods that may have handlers registered on it - to carry out actions on Saving of content for example.

This wasn't particularly straightforward but I got some help from this blog post by David Kowalski and a chapter he referenced from C# in Depth. The code I used to get this information was as follows:

public class ReflectedClassDto
{
    public string Name { get; set; }

    public string Namespace { get; set; }
}

public class CustomEventDto
{
    public string EventName { get; set; }

    public IEnumerable<ReflectedClassDto> Handlers { get; set; }
}

public IEnumerable<CustomEventDto> GetCustomEvents(IService serviceInstance)
{
    return serviceInstance.GetType().GetEvents()
        .Select(x => new CustomEventDto
        {
            EventName = x.Name,
            Handlers = GetCustomEventHandlers(serviceInstance, x)
        })
        .Where(x => x.Handlers != null && x.Handlers.Any());
}

private static IEnumerable GetCustomEventHandlers(IService serviceInstance, EventInfo eventInfo)
{
    var fi = GetEventField(serviceInstance, eventInfo);
    if (fi != null)
    {
        var del = fi.GetValue(serviceInstance) as Delegate;
        if (del != null)
        {
            return del.GetInvocationList()
                .Where(x => !x.Method.DeclaringType.FullName.ToLower().StartsWith("umbraco."))
                .Select(x => new ReflectedClassDto
                {
                    Name = x.Method.Name,
                    Namespace = x.Method.DeclaringType.FullName,
                });
        }
    }

    return null;
}

private static FieldInfo GetEventField(IService serviceInstance, EventInfo eventInfo)
{
    return serviceInstance.GetType()
        .GetField(eventInfo.Name,
            BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public |
            BindingFlags.FlattenHierarchy);
}

The first step is to get the list of events defined on the service instance - these are things like OnSaving etc - that have at least one handler defined. To get the event handlers we then extract the private field that backs the event and obtain the value of that field as a delegate (of type MulticastDelegate). With that there's a method called GetInvocationList() that allows you to retrieve all the defined handlers for the event. Again I remove all the ones that come with the Umbraco Core.

To see this in context see the open-source repository for the package and specifically this file.

Friday, 7 August 2015

(Yet) Another Look at Unit Testing Umbraco Surface Controllers

A quick recap

A little while back now I spent a bit of time investigating how one might go about unit testing Umbraco surface controllers. With the help of information posted by some others that had similarly looked into it I found there was a method that worked, but it wasn't ideal for a number of reasons.

Firstly there was a need to utilise an Umbraco test helpers dll, that contained implementations of various base classes that could be used to support testing. No great hardship to use that but it did mean you had to compile the source to get it and it led to some other restrictions on your tests.

One of those being you had to use NUnit. Again, a perfectly decent test runner but if you generally used MSTest or something else you had to make a switch.

And lastly in order to create various surface controller dependencies, you had to use some rather impenetrable looking reflection code to get around the fact that certain classes and methods were marked as internal rather than public. This worked, and only needed to be written once in a a base class to utilise it in all your tests, but was rather brittle. Code marked as internal is done so for a reason, one of those being that even if it's potentially useful to provide public access to developers, the core team haven't yet committed to the implementation so reserve the right to change it, even in a minor upgrade.

Putting all that together probably explains that although I did have a method that worked it wasn't something I made part of my general work with Umbraco.

The situation today

One thing I've been following and looking forward to the release of version 7.3 of Umbraco is the discussion on improved testing support. And given the recent release of this in beta, wanted to check it out.

Am pleased to report things are a lot easier now. There's still a bit of set-up and mocking code required, but that's unavoidable to ensure the surface controller has access to things like the Umbraco context in it's operations. But there are no base classes that you are required to depend on, no tie to a particular unit testing framework and no longer a requirement for reflection code.

As well as what follows, you can see some more examples of this in the Umbraco source code itself - which I used for reference. You can also take a look through the code of the Umbraco REST API which as noted in the comments below also contains several examples.

An example

I'll go back to the simple example I was looking to test in the previous blog post:

[HttpPost]
public ActionResult CreateComment(CommentViewModel model)
{
    if (!ModelState.IsValid)
    {
        return CurrentUmbracoPage();
    }

    TempData.Add("CustomMessage", "Thanks for your comment.");

    return RedirectToCurrentUmbracoPage();
}

And I have these two tests:

[TestMethod]
public void CreateComment_WithValidComment_RedirectsWithMessage()
{
    // Arrange
    var controller = GetController();
    var model = new CommentViewModel
    {
        Name = "Fred",
        Email = "fred@freddie.com",
        Comment = "Can I test this?",
    };

    // Act
    var result = controller.CreateComment(model);

    // Assert
    var redirectToUmbracoPageResult = result as RedirectToUmbracoPageResult;
    Assert.IsNotNull(redirectToUmbracoPageResult);
    Assert.AreEqual(1000, redirectToUmbracoPageResult.PublishedContent.Id);
    Assert.IsNotNull(controller.TempData["CustomMessage"]);
}

[TestMethod]
public void CreateComment_WithInValidComment_RedisplaysForm()
{
    // Arrange
    var controller = GetController();
    var model = new CommentViewModel
    {
        Name = "Fred",
        Email = string.Empty,
        Comment = "Can I test this?",
    };
    controller.ModelState.AddModelError("Email", "Email is required.");

    // Act
    var result = controller.CreateComment(model);

    // Assert
    var umbracoPageResult = result as UmbracoPageResult;
    Assert.IsNotNull(umbracoPageResult);
    Assert.IsNull(controller.TempData["CustomMessage"]);
}

To support testing there's a need to make a minor amend to the controller itself, to create a constructor that allows the passing of an instance (mocked for testing) of the Umbraco context and helper:

public class BlogPostSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
    private readonly UmbracoHelper _umbracoHelper;

    public BlogPostSurfaceController(UmbracoContext umbracoContext)
        : base(umbracoContext)
    {
    }

    public BlogPostSurfaceController(UmbracoContext umbracoContext, UmbracoHelper umbracoHelper)
        : base(umbracoContext)
    {
        _umbracoHelper = umbracoHelper;
    }

    public override UmbracoHelper Umbraco
    {
        get { return _umbracoHelper ?? base.Umbraco; }
    }
}

And then in the test project I need to implement the helper method I've created above called GetController(). I've placed all this code in my test class but in practice it would make sense to move much of this into your own test base class, so it can be reused across tests.

private BlogPostSurfaceController GetController()
{
    var appCtx = MockApplicationContext();
    var umbCtx = MockUmbracoContext(appCtx);

    var controller = new BlogPostSurfaceController(umbCtx, new UmbracoHelper(umbCtx));
    SetupControllerContext(umbCtx, controller);

    return controller;
}

private static ApplicationContext MockApplicationContext()
{
    return new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(),
        new ProfilingLogger(new Mock<ILogger>().Object, new Mock<IProfiler>().Object));
}

private static UmbracoContext MockUmbracoContext(ApplicationContext appCtx)
{
    return UmbracoContext.EnsureContext(
        new Mock<HttpContextBase>().Object,
        appCtx,
        new Mock<WebSecurity>(null, null).Object,
        Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "AutoLegacy")),
        Enumerable.Empty<IUrlProvider>(),
        true);
}

private static void SetupControllerContext(UmbracoContext umbCtx, Controller controller)
{
    var webRoutingSettings = Mock.Of<IWebRoutingSection>(section => section.UrlProviderMode == "AutoLegacy");
    var contextBase = umbCtx.HttpContext;
    var pcr = new PublishedContentRequest(new Uri("http://localhost/test"),
        umbCtx.RoutingContext,
        webRoutingSettings,
        s => Enumerable.Empty<string>())
    {
        PublishedContent = MockContent(),
    };

    var routeData = new RouteData();
    var routeDefinition = new RouteDefinition
    {
        PublishedContentRequest = pcr
    };
    routeData.DataTokens.Add("umbraco-route-def", routeDefinition);
    controller.ControllerContext = new ControllerContext(contextBase, routeData, controller);
}

private static IPublishedContent MockContent()
{
    return Mock.Of<IPublishedContent>(publishedContent => publishedContent.Id == 1000);            
}

Just for completeness, to run the code you will need to pull in the following from NuGet:

    PM> Install-Package UmbracoCms.Core -Pre
    PM> Install-Package Moq

And make sure you add framework references to System.Web, System.Configuration and System.Web.ApplicationServices.

The full list of using statements are as follows:

using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SurfaceControllerUnitTests.Controllers;
using SurfaceControllerUnitTests.Models;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Profiling;
using Umbraco.Web;
using Umbraco.Web.Mvc;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;

Great to see this improved testing support with the latest Umbraco. Not seen too much being made of it yet but for me an important part of this upcoming Umbraco release is it now being so much more accessible to testing.

Monday, 25 May 2015

2015 British General Election - Progressive Alliance What If?

Rather off topic for me on this blog but thought interesting nonetheless to publish... I was taken following the personally rather disappointing UK election results by a comment by the Green MP Caroline Lucas reported in the Guardian.

Reflecting on the result, she is quoted as saying...

The system is wrong and we should have electoral reform, but that could be some time coming. So we need other ways to work together in a progressive alliance. Where it is appropriate, only one progressive candidate could stand in a seat – a sort of electoral pact...

Which got me interested in the numbers, in particular considering what the change in the result might have been if such a pact was in place for 2015. Clearly there's a lot of assumption in this - not least the fact that I'm using the hindsight of the actual results to determine what might have been different, which is rather circular. It also assumes that every voter that would have voted say Liberal Democrat would be happy to vote for another party in the "alliance", which is unlikely to be 100% the case. It would certainly need some messaging effort between now and the next election to ensure people accepted that their party preference would be counted, albeit in a different constituency.

So to look at the numbers I downloaded the full set of results for all constituencies in England, Scotland and Wales, that is available from the British Election Study website. I then found all seats the Conservative won and worked out if they would still have won if one of two alliances were in place - firstly between the Liberal Democrats and the Greens, and secondly including Labour as well.

Having found the seats that would have changed hands in this scenario, I then looked at the actual votes cast for the "alliance" parties in these constituencies. I used this to calculate a fair means of allocating which actual party would be given the seat. Again this takes some liberties with timings - in reality the choice of which party was standing (and which was standing aside) in each seat would need to be made before voting of course. But it does seem like a reasonable basis for such a decision if something like this were planned for the next election.

Finally then looking at how this pans out. Firstly, in the scenario where there's an alliance between the Liberal Democrats and the Greens, there's a fairly minor change. Five seats would change hands, which given the breakdown I've used would give the Greens a further MP and the Liberal Democrats a slightly less disastrous loss of MPs to twelve instead of the eight they retained in reality. A significant Conservative majority would still have been the result.

Where things become more dramatic is if Labour is included. Pollitically this may be far-fetched, but electorially it would likely make sense - particularly in areas such as my home region of the South West, where they are third or fourth party at best in most constituencies. In this scenario, the Greens have five MPs, Liberal Democrats three times as many at twenty four and Labour an additional twenty six. The Conservatives remain the largest party but sixty short of an overall majority.

The data and analysis is available for view and review as a Google doc here.

Thursday, 21 May 2015

Sample Site for Merchello with Umbraco

For a while now, since last Codegarden in 2014 in fact, I've been planning to take a look at Merchello, an e-commerce framework for Umbraco. In the past I've made use of uCommerce which worked well for the project but the fact that, like Umbraco, Merchello is open-source is one factor that makes it attractive to consider for future projects.

So on and off for the past few weeks I've built out a very basic store site. Really doesn't look like much and has little in the way of bells and whistles, but implements a number of the core features required for an e-commerce website, namely:

  • Product category and product pages
  • Products with variants, with price and availability indicated for the particular variant selected
  • Basket page with quantity update and option to remove
  • Billing and shipping detail collection
  • Delivery method selection and application of postage & packing costs
  • Selection of payment method
  • Integration with a credit card processing provider, Authorize.Net
  • Presentation of confirmation screen

Nothing in the above is particularly off the beaten track when it comes to Merchello - there are a number of extension points available that I've not dug into yet.

That said, in building this out I did find myself digging into a number of documentation pages and examples (plus forum posts of course) which as is often the case with a fast moving project, sometimes struggle to keep up with the latest features.

I've also followed some stricter MVC patterns I like to use with Umbraco development, which is to use route hijacking, strongly typed POCO view models and mapping with Umbraco Mapper and AutoMapper from my Umbraco content and the Merchello APIs and objects respectively.

For both those reasons think it's worth sharing and may be of use for anyone else making a start with this product. Code is up at GitHub.