Testing code that uses Autofac + DependencyResolver in ASP.NET MVC

Sometimes it’s necessary to use DependencyResolver.Current in your MVC code where there is code that can’t be simply injected using your dependency injection framework. MVC provides a lot of extensibility points for things like model binding, model validation, and action filter, controller and view instantiation that mean that 90% of the time you can simply use your DI framework. This is made especially easy by frameworks like Autofac that provide easy MVC integration.

Use Case: Filter Provider

The main circumstance I’ve needed to use DependencyResolver.Current is in a filter provider (when trying to get precise control over globally applied filters and their execution order). I have tried passing through functors from Autofac that return the things I’m after, but you get Autofac resolution errors because it can’t tell what scope you are calling them from and if they are bound to, say, the HTTP lifetime then it can’t guarantee that the objects will be disposed correctly. There is possibly a way to inject something to correctly resolve the right Autofac lifetime scope, but I haven’t looked into it further.

An example such filter provider might be:

    public class MyAppFilterProvider : IFilterProvider
    {
        private readonly Environment _currentEnvironment;

        public MyAppFilterProvider(Environment currentEnvironment)
        {
            // Injected from Autofac
            _currentEnvironment = currentEnvironment;
        }

        public IEnumerable GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {

            // Ensure all pages other than the homepage are HTTPS in production
            if (_currentEnvironment == Environment.Prod && !(actionDescriptor.ActionName == "Index" && controllerContext.Controller.GetType() == typeof(StaticPageController)))
            {
                yield return new Filter(new RequireHttpsAttribute(), FilterScope.First, -5);
            }

            // Resolve the "current user" filter including any dependencies it may have
            // This could do something like, say put a reference to the current user from the database into the ViewBag so it can be accessed by the controller and the view
            var currentUserFilter = DependencyResolver.Current.GetService();
            yield return new Filter(currentUserFilter, FilterScope.First, -1);
        }
    }

Testing when there are calls to Dependency Resolver

Because we make use of DependencyResolver we need to be able to test it. This is trickier than it seems when using Autofac since if you resolve a service from the dependency resolver when there is no HttpContext then it will fail with “System.InvalidOperationException : The request lifetime scope cannot be created because the HttpContext is not available”. This problem may well affect other DI frameworks as well.

There are two options to combat this:

  • Create a custom class to resolve dependencies for that/those specific test/s and set it using DependencyResolver.SetResolver(new MyTestDependencyResolver()), but this could become tedious to maintain and complicates your test
  • Simulate a HTTP context by using HttpSimulator, it’s easy to install via NuGet (thanks Matt): Install-Package HttpSimulator

When testing I use an Autofac container that automatically resolves interfaces as NSubstitute Substitutes (there are similar packages for other mocking frameworks, check out Autofac.Contrib). The following code is an example of how you can set up a test:

    public class ClassThatUsesDependencyResolver
    {
        public ClassThatUsesDependencyResolver()
        {
            var service = DependencyResolver.Current.GetService();
            service.Get(1);
        }
    }

    [TestFixture]
    class DependencyResolverTests
    {
        private AutoMock _autoMock;
        private HttpSimulator _httpSimulator;

        [SetUp]
        public void Setup()
        {
            _autoMock = new AutoMock();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(_autoMock.Container));
            _httpSimulator = new HttpSimulator().SimulateRequest();
        }

        [TearDown]
        public void Teardown()
        {
            _httpSimulator.Dispose();
        }

        [Test]
        public void Test()
        {
            new ClassThatUsesDependencyResolver();
            DependencyResolver.Current.GetService().Received().Get(1);
        }
    }

One thing to note is that I used DependencyResolver.Current in the test rather than _autoMock.Resolve<…>() because the scoping that Autofac has is such that they resolve as different objects (which can be a bit confusing).

Testing the filter provider

Given I’ve shown an example filter provider above I figure I should demonstrate some of the tests that I have done in the past. There are two main things to test as far as I see (which you test for or indeed if you test for both (or don’t test it at all) depends on your situation – be pragmatic):

  • Test the order that the filters get applied is as you expect (you don’t want database calls for the current user before passive (e.g. single-sign-on) authentication is processed for instance…
  • Test that in certain circumstances a filter is applied (or not!)

An example showing both for the above filter provider is given below:

    [TestFixture]
    class MyAppFilterProviderShould
    {
        private AutoMock _autoMock;
        private HttpSimulator _httpSimulator;
        private ControllerContext _controllerContext;
        private ActionDescriptor _actionDescriptor;

        [SetUp]
        public void Setup()
        {
            _autoMock = new AutoMock();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(_autoMock.Container));
            _httpSimulator = new HttpSimulator().SimulateRequest();
            _controllerContext = Substitute.For<ControllerContext>();
            _actionDescriptor = Substitute.For<ActionDescriptor>();
        }

        [TearDown]
        public void Teardown()
        {
            _httpSimulator.Dispose();
        }

        private IEnumerable<Filter> GetFilters(Environment environment)
        {
            var filterProvider = new MyAppFilterProvider(environment);
            return filterProvider.GetFilters(_controllerContext, _actionDescriptor);
        }

        [Test]
        public void Resolve_filters_in_correct_order()
        {
            var filters = GetFilters(Environment.Prod).ToList().OrderBy(f => f.Scope).OrderBy(f => f.Order).ToList();
            var index = 0;
            Assert.That(filters[index++].Instance, Is.TypeOf<RequireHttpsAttribute>()); // Require Https should always be run first
            Assert.That(filters[index++].Instance, Is.TypeOf<CurrentUserFilter>());
            Assert.That(filters, Has.Count.EqualTo(index)); // This ensures we update the test when more filters are added
        }

        [Test]
        public void Not_require_https_when_not_in_production([Values(Environment.Dev, Environment.CI, Environment.Test)] Environment environment)
        {
            Assert.That(GetFilters(environment).Select(f => f.Instance), Has.None.TypeOf<RequireHttpsAttribute>());
        }

        [Test]
        public void Not_require_https_for_homepage_in_production()
        {
            _controllerContext.Controller = _autoMock.Resolve<StaticPageController>();
            _actionDescriptor.ActionName.Returns("Index");
            Assert.That(GetFilters(Environment.Prod).Select(f => f.Instance), Has.None.TypeOf<RequireHttpsAttribute>());
        }
    }

Update (23/03/2013)

It might not be necessary to ever use DependencyResolver.Current any more due to a new technique I’ve found.

Unobtrusive Validation in ASP.NET MVC 3 and 4

Most things that can be done to reduce the amount of code that you need to write to get the same outcome (keeping in mind that you still need code to be easily readable/understandable for maintainability reasons) is great. The less code you have the less change of a bug, the less code to maintain, the less code that needs to be modified to add a new feature and the easier (hopefully) the overall solution is to understand.

In particular, if plumbing code that doesn’t actually serve any purpose other than to join the useful bits of code can be negated then that will usually significantly increase readability and maintainability of code. It’s also this sort of boring, monotonous code that often contains little errors that get missed because of the blight of CPDD (copy-paste-driven-development) where you copy a few lines of code, plonk them somewhere else and then change a couple of the class names or magic strings around. Inevitably you will miss one of two of the references and this is often combined with the fact that this type of code is likely not tested (depending on how strict your testing regime is).

Thus, one of the things that my team and I have put energy into over the last year and a half while we progress on our ASP.NET MVC journey is how to reduce this type of code. The first technique that springs to mind to combat this type of plumbing code is convention over configuration and to that end we have come up with unobtrusive techniques for model binding and validation that make heavy use of our dependency injection framework (Autofac). While the techniques I’ll demonstrate make use of Autofac, I imagine similar techniques can be used for the other frameworks.

Example code

This post is accompanied by some example code.

Data type validation

The DefaultModelBinder class that comes with MVC is pretty magical; it managed to parse the various values from the various scopes submitted with a request e.g. get and post values, etc. by name to your (potentially nested)  view model by name and pops any validation errors that it encounters in the Model State for you. Then a simple call to ModelState.IsValid in your controller will tell you if the view model was ok! This includes things like putting your data type as int and checking the input the user submitted was an integer and the same for any primitive types or enumerations! Furthermore, any custom types you define can have validation logic associated with them that will get automatically triggered (see my blog post for an example; look at the code for the custom type).

Thus, if you are taking user input in a controller action you will likely want code like this:

        public ActionResult SomeAction(SomeViewModel vm)
        {
            if (!ModelState.IsValid)
                return View(vm);

            // todo: Perform the action
        }

System.ComponentModel.DataAnnotations

By default in MVC you are given a number of unobtrusive validation options from the System.ComponentModel.DataAnnotations namespace, you can see the list of classes included on MSDN, but here is a quick rundown of the notable ones:

  • [DataType(DataType.Something)] – by default doesn’t actually perform any (server-side) validation, although you can use this to perform custom validation. It’s mostly used to provide metadata for UI controls to affect the display of the data. This is one of the confusing things about the DataAnnotations namespace – you would reasonably expect that this attribute would perform validation on first inspection!
  • [Display(“Label text”)] – Override the label text, although if you use this for every field because the default display of the field name when there is multiple words in camel case is ugly then you might want to define a custom metadata provider instead.
  • [Range(min, max)] – Specify a numerical range
  • [RegularExpression(regex)] – Specify a regex the data has to conform to
  • [Required] – enough said, although one thing to note is that non-nullable types like int, double etc. are implicitly required so the omission (or inclusion) of this attribute will have no effect. If you want to have an int that isn’t required make the type int? (or Nullable<int> if you like typing).
  • [StringLength(MinimumLength = minLength, MaximumLength = maxLength)] – Specify a min and/or max character length for a string

It should be noted that you are given the option of overriding the default error message for any of these attributes.

Data Annotations Extensions

The default set of unobtrusive data validation annotations can be extended with a much more useful set of validations via the Data Annotations Extensions project, which includes server- and client-side validation for:

  • Credit cards
  • Dates
  • Digits
  • Emails
  • Cross-property equality
  • File extensions
  • Digits and other numerical validations
  • Urls
  • Years

It’s pretty easy to get up and running with them too via NuGet:

Install-Package DataAnnotationsExtensions.MVC3

Custom Validation

Sometimes simply validating that the data type and format of your view model properties just isn’t enough, what if you want to validate that a URL returns a 200 OK, or that the username the user provided isn’t already in your database?

In this instance we need to turn to performing custom validation. There are a number of ways this could be done:

  1. Put custom validation code directly in your controller after checking ModelState.IsValid
    • Tedious and awful separation of concerns, plus we will still need to use model state (if you want errors to propagate to the UI via Html.ValidationMessageFor(…) or similar) and thus have a second call to check ModelState.IsValid
  2. Wrap the custom validation code into a helper or extension method and calling it from the controller after checking ModelState
    • More reusable if you use the view model multiple times and makes the controller action easier to test and understand, still tedious though
  3. Use one of the custom validation approaches to call the validation code
    • Even better separation of concerns since the model errors will now appear in model state when the controller action is called, but still reasonably tedious
  4. Use a validation library to take away the tedium (my favourite is Fluent Validation)
    • Getting there, but the amount of code to write increased :(…
  5. Use an MVC ModelValidatorProvider and reflection to unobtrusively apply the validation using the default model binder without having to implement IValidatableObject for every view model
    • Almost there, we still have to statically call DependencyResolver.Current to get any database repositories or similar, which is painful to test
    • In my case I’m using the MVC integration that the FluentValidation library provides to automatically pick up the correct validator, but you could obviously write your own ModelValidatorProvider, for this to work it simply requires that you add the [Validator(typeof(ValidatorClass)] attribute on your view models
  6. Integrate with your DI framework to inject dependencies to the unobtrusively called validator
    • Perfect!
    • Props to my Senior Developer Matthew Davies for coming up with this technique

I’ve ordered the list above in pretty much the order of approaches that we went through to get to where we are now. I’ve included a comparison of the different approaches in the Github repo for this blog post. Note that I’ve bundled all the code for each approach into a region when in reality the validation classes should be separated, but it makes it easier to compare the different approaches this way.

I should note that there is another approach I neglected to mention, which is to create a custom model binder for the view model and to perform the validation and setting of model state in there rather than the controller. While this is a better separation of concerns than putting the code in the controller, it still leaves a lot to be desired and can be quite tedious. On occasion, when you actually need to use custom model binding (e.g. not just for validation) it can become important to put errors in the model state though.

Conclusions

Now, the example code I’ve written doesn’t really give a good indication of the advantages of the final solution (that I recommend). This is mainly because I was only performing a single view model validation on a single property of that validation – the more custom validation you have the more the unobtrusive solution shines. It’s also worth noting that your test code will become significantly less complex for each example I gave though as well. Another consideration is that the unobtrusive code, while it means you have to write less code all up does hide away a lot of what is happening in “magic”. For someone new to the solution this could pose a problem and make the solution hard to understand and for this reason if you are using this approach I recommend it forms a part of the (brief) documentation of your solution that supplements the code and tests.

At the end of the day, you should take a pragmatic approach, if all you need is one or two really simple validations then you probably don’t need to put in the code for the unobtrusive validation and at that point the unobtrusive validation will probably complicate rather than simplify your solution. If you are lucky enough to have some sort of base libraries that you use across projects and you have a consistent team that are familiar with it’s use then it makes sense to abstract away the unobtrusive validation code so that you can simply be up and running with it straight away for all projects.

Nice label names in ASP.NET MVC 3

By default in ASP.NET MVC the label names when you use the Html.LabelFor() method are simply the property name. This is great for single word properties like Email or Name, but quickly falls apart when you have properties like EmailAddress, and FirstName.

If you have a convention for your label names (at Curtin our forms standard states we need to have Sentence case labels) then you can save yourself a lot of hassle (e.g. having to specify [DisplayName(“…”)] on most of the properties) by simply defining a custom metadata provider. For example, the one we use is:

    public class MetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, 
            Func<object> modelAccessor, Type modelType, string propertyName)
        {
            // Default metadata implementations
            var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);

            // Auto-sentence case for display name
            if (metadata.DisplayName == null && metadata.PropertyName != null)
            {
                metadata.DisplayName = metadata.PropertyName.UnCamelCaseify();
            }

            return metadata;
        }
    }

Then you simply need the following one-liner in Global.asax.cs in Application_Start() to hook it up:

ModelMetadataProviders.Current = new MetadataProvider();

The UnCamelCaseify() extension method simply translates from CamelCase to Sentence case.

Obviously, for complex label names you will simply use the DisplayName attribute, but I find that more than 80% of the time the sentence case conversion works a treat, which is thus a nice time saver and results in less code, which is only a good thing!

Data type validation in ASP.NET MVC 3

This post outlines some experimentation that was conducted to find the different approaches that can be taken to perform data type validation in ASP.NET MVC 3 (when binding a view model).

I did some work on this over a year ago with Miguel Madero when he was doing some consulting work with my team. Frankly, I’m confused that I can’t find a post on my blog about it because I swear that I did one.

Regardless, this one is a fairly easy post to write because it’s basically easier said in code. As such I’ll direct you to the Github repository we created and put a small explanation below.

What do I mean by data type validation?

I mean validating the semantic form of the data – e.g. is it an integer number, is it an email address, is it one of a number of enumeration values? etc. I don’t mean validating the format of the data or the metadata or properties of the data – e.g. does it have a length greater than x characters, is it smaller than number y, does it conform to a given regular expression, is it the same as another property in the view model?

I realise that the line between data type and data format can be blurred, particularly when it comes to strings, so another way to put it is that I’m referring to the primary validation you will perform before being able to assign the data to the given property in the view model. Then on top of that you might want to perform other validations.

What are the ways that you can perform this validation in ASP.NET MVC?

We found three ways, feel free to post a comment if you discover any other ways and I’ll be happy to include that in the Github repo (or even better send me a pull request):

  • Custom validation attributes; e.g.
    [Digits]
    public string DigitsWithCustomAttribute { get; set; }
    
  • Custom Data Type attribute; e.g.
    [DataType("Digits")]
    public string DigitsWithDataTypeAttribute { get; set; }
    
  • Custom type; e.g.
    public Digits DigitsAsCustomType { get; set; }

Motivation and findings

The reason why we did this was because at the time the documentation for how to perform custom data type validation (outside of the build-in validation MVC provides) was confusing and lacking. It may have improved since then though…

At the end of the day, the easiest to implement was the custom validation attribute, but the nicest and tersest end result was from the most complex to implement in the custom type. I should note that one of the cool things (that all three methods supported) is that you can pass metadata to the JavaScript for client-side validation (you will have to write JavaScript validation code as well though for anything that jQuery Validate doesn’t support out of the box). The way that Microsoft have implemented this through their unobtrusive client validation code is pretty clever and well thought out :).

The readme file for the Github repository explains where to look to find the relevant code.

Enjoy!

… A year later

It seems rather funny that it was exactly one year since I’ve done a post on my blog. Usual story of course, I started out with good intentions to regularly blog about all the cool stuff I discover along my journey, but time got the better of me. I guess they were the same intentions that I originally had to skin this blog :S.

One thing I have learnt over the last year is that prioritisation is one of the most important things you can do and abide by both personally and professionally. No matter what there will never be enough time to do all the things that you need and want to do so you just have to prioritise and get done all you can – what more can you ask of yourself. With that in mind I guess I haven’t prioritised my blog 😛

I really respect people that manage to keep up with regular blog posts as well as full-time work and other activities. I find that writing blog posts is really time consuming because the pedantic perfectionist in me strives to get every relevant little detail in there and ensure it’s all formatted correctly. Combining that with the insane number of things I seem to find myself doing and trying to get some relax time in somewhere isn’t terribly conducive. It’s a pity really because I enjoy writing posts and hopefully I contribute some useful information here and there.

So, that aside, what have I been doing for the last year. If you are interested feel free to peruse the below list, which has some of what I’ve been doing and is written in no particular order; it’s really just a brain dump ^^. There are a few posts that I have been intending on writing along the way with particularly interesting (to me at least) topics so I’ll try and write some posts over the next few days 🙂

  • Worked with out Project Management Office at work to come up with a way to use PRINCE 2 to provide high level project management to our Agile projects without impacting on the daily work that the teams perform under Scrum. Despite my early scepticism about PRINCE 2 it’s actually a really impressive and flexible project management framework and has worked well.
  • Learnt PowerShell – it’s amazing!
  • Wrote some interesting / powerful NuGet packages (not public I’m afraid) using PowerShell install scripts
  • Attended a really great conference
  • Discovered and started living and breathing (and evangelising) continuous delivery and dev ops
  • Started thinking about the concept of continuous design as presented by Mary Poppendieck at Yow
  • Created a continuous delivery pipeline for a side-project with a final prod deployment to Windows Azure controlled by the product owner at the click of a button with a 30-45s deployment time!
  • Started learning about the value of Lean thinking, in particular with operational teams
  • Started evangelising lean thinking to management and other teams at work (both software and non-software)
  • Started using Trello to organise pretty much everything (both for my team, myself personally and at work and various projects I’m working on in and out of work) – it’s AMAZING.
  • Delivered a number of interesting / technically challenging projects
  • Became a manager
  • Assisted my team to embark on the biggest project we’ve done to date
  • Joined a start-up company based in Melbourne in my spare time
  • Joined Linked in (lol; I guess it had to finally happen)
  • Gave a number of presentations
  • Became somewhat proficient in MSBuild (*shudders*) and XDT
  • Facilitated countless retrospectives including a few virtual retrospectives (ahh Trello, what would I do without you)
  • Consolidated my love for pretty much everything Jetbrains produce for .NET (in particular TeamCity 7 and ReSharper 6 are insanely good, I’ll forgive them for dotCover)
  • Met Martin Fowler and Mary and Tom Poppendieck
  • Participated in the global day of code retreat and then ran one for my team (along with a couple of Fedex days)
  • Got really frustrated with 2GB of RAM on my 3 year old computer at home after I started doing serious development on it (with the start-up) and upgraded to 6GB (soooo much better, thanks Evan!)
  • Participated on a couple of panels for my local Agile meetup group
  • Got an iPhone 4S 🙂 (my 3GS was heavily on the blink :S)
  • Took over as chairman of the young professionals committee for the local branch of the Institution of Engineering and Technology
  • Deepened my experience with Microsoft Azure and thoroughly enjoyed all the enhancements they have made – they have gone a long way since I first started in 2010!

Of course there is heaps more, but this will do for now.