Skip to content

Jimmy Bogard
Syndicate content
Strong opinions, weakly held
Updated: 5 hours 32 min ago

Container Usage Guidelines

Wed, 09/17/2014 - 21:25

Over the years, I’ve used and abused IoC containers. While the different tools have come and gone, I’ve settled on a set of guidelines on using containers effectively. As a big fan of the Framework Design Guidelines book and its style of “DO/CONSIDER/AVOID/DON’T”, I tried to capture what has made me successful with containers over the years in a series of guidelines below.

Container configuration

Container configuration typically occurs once at the beginning of the lifecycle of an AppDomain, creating an instance of a container as the composition root of the application, and configuring and framework-specific service locators. StructureMap combines scanning for convention-based registration, and Registries for component-specific configuration.

X AVOID scanning an assembly more than once.

Scanning is somewhat expensive, as scanning involves passing each type in an assembly through each convention. A typical use of scanning is to target one or more assemblies, find all custom Registries, and apply conventions. Conventions include generics rules, matching common naming conventions (IFoo to Foo) and applying custom conventions. A typical root configuration would be:

var container = new Container(cfg =>
    cfg.Scan(scan => {
        scan.AssemblyContainingType<IMediator>();
        scan.AssemblyContainingType<UiRegistry>();
 
        scan.AddAllTypesOf(typeof(IValidator<>));
        scan.AddAllTypesOf(typeof(IRequestHandler<,>));
 
        scan.WithDefaultConventions();
        scan.LookForRegistries();
    }));

Component-specific configuration is then separated out into individual Registry objects, instead of mixed with scanning. Although it is possible to perform both scanning and component configuration in one step, separating component-specific registration in individual registries provides a better separation of conventions and configuration.

√ DO separate configuration concerning different components or concerns into different Registry classes.

Individual Registry classes contain component-specific registration. Prefer smaller, targeted Registries, organized around function, scope, component etc. All container configuration for a single 3rd-party component organized into a single Registry makes it easy to view and modify all configuration for that one component:

public class NHibernateRegistry : Registry {
    public NHibernateRegistry() {
        For<Configuration>().Singleton().Use(c => new ConfigurationFactory().CreateConfiguration());
        For<ISessionFactory>().Singleton().Use(c => c.GetInstance<Configuration>().BuildSessionFactory());
 
        For<ISession>().Use(c => {
            var sessionFactory = c.GetInstance<ISessionFactory>();
            var orgInterceptor = new OrganizationInterceptor(c.GetInstance<IUserContext>());
            return sessionFactory.OpenSession(orgInterceptor);
        });
    }
}

X DO NOT use the static API for configuring or resolving.

Although StructureMap exposes a static API in the ObjectFactory class, it is considered obsolete. If a static instance of a composition root is needed for 3rd-party libraries, create a static instance of the composition root Container in application code.

√ DO use the instance-based API for configuring.

Instead of using ObjectFactory.Initialize and exposing ObjectFactory.Instance, create a Container instance directly. The consuming application is responsible for determining the lifecycle/configuration timing and exposing container creation/configuration as an explicit function allows the consuming runtime to determine these (for example, in a web application vs. integration tests).

X DO NOT create a separate project solely for dependency resolution and configuration.

Container configuration belongs in applications requiring those dependencies. Avoid convoluted project reference hierarchies (i.e., a “DependencyResolution” project). Instead, organize container configuration inside the projects needing them, and defer additional project creation until multiple deployed applications need shared, common configuration.

√ DO include a Registry in each assembly that needs dependencies configured.

In the case where multiple deployed applications share a common project, include inside that project container configuration for components specific to that project. If the shared project requires convention scanning, then a single Registry local to that project should perform the scanning of itself and any dependent assemblies.

X AVOID loading assemblies by name to configure.

Scanning allows adding assemblies by name, “scan.Assembly(“MyAssembly”)”. Since assembly names can change, reference a specific type in that assembly to be registered. 
Lifecycle configuration

Most containers allow defining the lifecycle of components, and StructureMap is no exception. Lifecycles determine how StructureMap manages instances of components. By default, instances for a single request are shared. Ideally, only Singleton instances and per-request instances should be needed. There are cases where a custom lifecycle is necessary, to scope a component to a given HTTP request (HttpContext).

√ DO use the container to configure component lifecycle.

Avoid creating custom factories or builder methods for component lifecycles. Your custom factory for building a singleton component is probably broken, and lifecycles in containers have undergone extensive testing and usage over many years. Additionally, building factories solely for controlling lifecycles leaks implementation and environment concerns to services consuming lifecycle-controlled components. In the case where instantiation needs to be deferred or lifecycle needs to be explicitly managed (for example, instantiating in a using block), depending on a Func<IService> or an abstract factory is appropriate.

√ CONSIDER using child containers for per-request instances instead of HttpContext or similar scopes.

Child/nested containers inherit configuration from a root container, and many modern application frameworks include the concept of creating scopes for requests. Web API in particular creates a dependency scope for each request. Instead of using a lifecycle, individual components can be configured for an individual instance of a child container:

public IDependencyScope BeginScope() {
    IContainer child = this.Container.GetNestedContainer();
    var session = new ApiContext(child.GetInstance<IDomainEventDispatcher>());
    var resolver = new StructureMapDependencyResolver(child);
    var provider = new ServiceLocatorProvider(() => resolver);
    child.Configure(cfg =>
    {
        cfg.For<DbContext>().Use(session);
        cfg.For<ApiContext>().Use(session);
        cfg.For<ServiceLocatorProvider>().Use(provider);
    });
             
    return resolver;
}

Since components configured for a child container are transient for that container, child containers provide a mechanism to create explicit lifecycle scopes configured for that one child container instance. Common applications include creating child containers per integration test, MVVM command handler, web request etc.

√ DO dispose of child containers.

Containers contain a Dispose method, so if the underlying service locator extensions do not dispose directly, dispose of the container yourself. Containers, when disposed, will call Dispose on any non-singleton component that implements IDisposable. This will ensure that any resources potentially consumed by components are disposed properly.
Component design and naming

Much of the negativity around DI containers arises from their encapsulation of building object graphs. A large, complicated object graph is resolved with single line of code, hiding potentially dozens of disparate underlying services. Common to those new to Domain-Driven Design is the habit of creating interfaces for every small behavior, leading to overly complex designs. These design smells are easy to spot without a container, since building complex object graphs by hand is tedious. DI containers hide this pain, so it is up to the developer to recognize these design smells up front, or avoid them entirely.

X AVOID deeply nested object graphs.

Large object graphs are difficult to understand, but easy to create with DI containers. Instead of a strict top-down design, identify cross-cutting concerns and build generic abstractions around them. Procedural code is perfectly acceptable, and many design patterns and refactoring techniques exist to address complicated procedural code. The behavioral design patterns can be especially helpful, combined with refactorings dealing with long/complicated code can be especially helpful. Starting with the Transaction Script pattern keeps the number of structures low until the code exhibits enough design smells to warrant refactoring.

√ CONSIDER building generic abstractions around concepts, such as IRequestHandler<T>, IValidator<T>.

When designs do become unwieldy, breaking down components into multiple services often leads to service-itis, where a system contains numerous services but each only used in one context or execution path. Instead, behavioral patterns such as the Mediator, Command, Chain of Responsibility and Strategy are especially helpful in creating abstractions around concepts. Common concepts include:

  • Queries
  • Commands
  • Validators
  • Notifications
  • Model binders
  • Filters
  • Search providers
  • PDF document generators
  • REST document readers/writers

Each of these patterns begins with a common interface:

public interface IRequestHandler<in TRequest, out TResponse>
    where TRequest : IRequest<TResponse> {
    TResponse Handle(TRequest request);
}
 
public interface IValidator<in T> {
    ValidationResult Validate(T instance);
}
 
public interface ISearcher {
    bool IsMatch(string query);
    IEnumerable<Person> Search(string query);
}

Registration for these components involves adding all implementations of an interface, and code using these components request an instance based on a generic parameter or all instances in the case of the chain of responsibility pattern.

One exception to this rule is for third-party components and external, volatile dependencies.

√ CONSIDER encapsulating 3rd-party libraries behind adapters or facades.

While using a 3rd-party dependency does not necessitate building an abstraction for that component, if the component is difficult or impossible to fake/mock in a test, then it is appropriate to create a facade around that component. File system, web services, email, queues and anything else that touches the file system or network are prime targets for abstraction.

The database layer is a little more subtle, as requests to the database often need to be optimized in isolation from any other request. Switching database/ORM strategies is fairly straightforward, since most ORMs use a common language already (LINQ), but have subtle differences when it comes to optimizing calls. Large projects can switch between major ORMs with relative ease, so any abstraction would limit the use of any one ORM into the least common denominator.

X DO NOT create interfaces for every service.

Another common misconception of SOLID design is that every component deserves an interface. DI containers can resolve concrete types without an issue, so there is no technical limitation to depending directly on a concrete type. In the book Growing Object-Oriented Software, Guided by Tests, these components are referred to as Peers, and in Hexagonal Architecture terms, interfaces are reserved for Ports.

√ DO depend on concrete types when those dependencies are in the same logical layer/tier.

A side effect of depending directly on concrete types is that it becomes very difficult to over-specify tests. Interfaces are appropriate when there is truly an abstraction to a concept, but if there is no abstraction, no interface is needed.

X AVOID implementation names whose name is the implemented interface name without the “I”.

StructureMap’s default conventions do match up IFoo with Foo, and this can be a convenient default behavior, but when you have implementations whose name is the same as their interface without the “I”, that is a symptom that you are arbitrarily creating an interface for every service, when just resolving the concrete service type would be sufficient instead.  In other words, the mere ability to resolve a service type by an interface is not sufficient justification for introducing an interface.

√ DO name implementation classes based on details of the implementation (AspNetUserContext : IUserContext).

An easy way to detect excessive abstraction is when class names are directly the interface name without the prefix “I”. An implementation of an interface should describe the implementation. For concept-based interfaces, class names describe the representation of the concept (ChangeNameValidator, NameSearcher etc.) Environment/context-specific implementations are named after that context (WebApiUserContext : IUserContext).
Dynamic resolution

While most component resolution occurs at the very top level of a request (controller/presenter), there are occasions when dynamic resolution of a component is necessary. For example, model binding in MVC occurs after a controller is created, making it slightly more difficult to know at controller construction time what the model type is, unless it is assumed using the action parameters. For many extension points in MVC, it is impossible to avoid service location.

X AVOID using the container for service location directly.

Ideally, component resolution occurs once in a request, but in the cases where this is not possible, use a framework’s built-in resolution capabilities. In Web API for example, dynamically resolved dependencies should be resolved from the current dependency scope:

var validationProvider = actionContext
    .Request
    .GetDependencyScope()
    .GetService(typeof(IValidatorProvider));

Web API creates a child container per request and caches this scoped container within the request message. If the framework does not provide a scoped instance, store the current container in an appropriately scoped object, such as HttpContext.Items for web requests. Occasionally, you might need to depend on a service but need to explicitly decouple or control its lifecycle. In those cases, containers support depending directly on a Func.

√ CONSIDER depending on a Func<IService> for late-bound services.

For cases where known types need to be resolved dynamically, instead of trying to build special caching/resolution services, you can instead depend on a constructor function in the form of a Func. This separates wiring of dependencies from instantiation, allowing client code to have explicit construction without depending directly on a container.

public EmailController(Func<IEmailService> emailServiceProvider) {
    _emailServiceProvider = emailServiceProvider;
}
 
public ActionResult SendEmail(string to, string subject, string body) {
    using (var emailService = _emailServiceProvider()) {
        emailService.Send(to, subject, body);
    }
}

In cases where this becomes complicated, or reflection code is needed, a factory method or delegate type explicitly captures this intent.

√ DO encapsulate container usage with factory classes when invoking a container is required.

The Patterns and Practices Common Service Locator defines a delegate type representing the creation of a service locator instance:

public delegate IServiceLocator ServiceLocatorProvider();

For code needing dynamic instantiation of a service locator, configuration code creates a dependency definition for this delegate type:

public IDependencyScope BeginScope()
{
    IContainer child = this.Container.GetNestedContainer();
    var resolver = new StructureMapWebApiDependencyResolver(child);
    var provider = new ServiceLocatorProvider(() => resolver);
    child.Configure(cfg =>
    {
        cfg.For<ServiceLocatorProvider>().Use(provider);
    });
    return new StructureMapWebApiDependencyResolver(child);
}

This pattern is especially useful if an outer dependency has a longer configured lifecycle (static/singleton) but you need a window of shorter lifecycles. For simple instances of reflection-based component resolution, some containers include automatic facilities for creating factories.

√ CONSIDER using auto-factory capabilities of the container, if available.

Auto-factories in StructureMap are available as a separate package, and allow you to create an interface with an automatic implementation:

public interface IPluginFactory {
    IList<IPlugin> GetPlugins();
}
 
For<IPluginFactory>().CreateFactory();

The AutoFactories feature will dynamically create an implementation that defers to the container for instantiating the list of plugins.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Tackling cross-cutting concerns with a mediator pipeline

Tue, 09/09/2014 - 18:17

Originally posted on the Skills Matter website

In most of the projects I’ve worked on in the last several years, I’ve put in place a mediator to manage the delivery of messages to handlers. I’ve covered the motivation behind such a pattern in the past, where it works well and where it doesn’t.

One of the advantages behind the mediator pattern is that it allows the application code to define a pipeline of activities for requests, as opposed to embedding this pipeline in other frameworks such as Rails, node.js, ASP.NET Web API and so on. These frameworks have many other concerns going on besides the very simple “one model in, one model out” pattern that so greatly simplifies conceptualizing the system and realizing more powerful patterns.

As a review, a mediator encapsulates how a series of objects interact. Our mediator looks like:

public interface IMediator
{
    TResponse Send<TResponse>(IRequest<TResponse> request);
    Task<TResponse> SendAsync<TResponse>(IAsyncRequest<TResponse> request);
    void Publish<TNotification>(TNotification notification) where TNotification : INotification;
    Task PublishAsync<TNotification>(TNotification notification) where TNotification : IAsyncNotification;
}

This is from a simple library (MediatR) I created (and borrowed heavily from others) that enables basic message passing. It facilitates loose coupling between how a series of objects interact. And like many OO patterns, it exists because of missing features in the language. In other functional languages, passing messages to handlers is accomplished with features like pattern matching.

Our handler interface represents the ability to take an input, perform work, and return some output:

public interface IRequestHandler<in TRequest, out TResponse>
    where TRequest : IRequest<TResponse>
{
    TResponse Handle(TRequest message);
}

With this simple pattern, we encapsulate the work being done to transform input to output in a single method. Any complexities around this work are encapsulated, and any refactorings are isolated to this one method. As systems become more complex, isolating side-effects becomes critical for maintaining overall speed of delivery and minimizing risk.

We still have the need for cross-cutting concerns, and we’d rather not pollute our handlers with this work.

These surrounding behaviors become implementations of the decorator pattern. Since we have a uniform interface of inputs and outputs, building decorators around cross-cutting concerns becomes trivial.

Pre- and post-request handlers

One common request I see is to do work on the requests coming in, or post-process the request on the way out. We can define some interfaces around this:

public interface IPreRequestHandler<in TRequest> {
    void Handle(TRequest request);
}

public interface IPostRequestHandler<in TRequest, in TResponse> {
    void Handle(TRequest request, TResponse response);
}

With this, we can modify inputs before they arrive to the main handler or modify responses on the way out.

In order to execute these handlers, we just need to define a decorator around our main handler:

public class MediatorPipeline<TRequest, TResponse> 
    : IRequestHandler<TRequest, TResponse> 
    where TRequest : IRequest<TResponse> {

    private readonly IRequestHandler<TRequest, TResponse> _inner;
    private readonly IPreRequestHandler<TRequest>[] _preRequestHandlers;
    private readonly IPostRequestHandler<TRequest, TResponse>[] _postRequestHandlers;

    public MediatorPipeline(
        IRequestHandler<TRequest, TResponse> inner,
        IPreRequestHandler<TRequest>[] preRequestHandlers,
        IPostRequestHandler<TRequest, TResponse>[] postRequestHandlers
        ) {
        _inner = inner;
        _preRequestHandlers = preRequestHandlers;
        _postRequestHandlers = postRequestHandlers;
    }

    public TResponse Handle(TRequest message) {

        foreach (var preRequestHandler in _preRequestHandlers) {
            preRequestHandler.Handle(message);
        }

        var result = _inner.Handle(message);

        foreach (var postRequestHandler in _postRequestHandlers) {
            postRequestHandler.Handle(message, result);
        }

        return result;
    }
}

And if we’re using a modern IoC container (StructureMap in this case), registering our decorator is as simple as:

cfg.For(typeof (IRequestHandler<,>))
   .DecorateAllWith(typeof (MediatorPipeline<,>));

When our mediator builds out the handler, it delegates to our container to do so. Our container builds the inner handler, then surrounds the handler with additional work. If this seems familiar, many modern web frameworks like koa include a similar construct using continuation passing to define a pipeline for requests. However, since our pipeline is defined in our application layer, we don’t have to deal with things like HTTP headers, content negotiation and so on.

Validation

Most validation frameworks I use validate against a type, whether it’s validation with attributes or delegated validation to a handler. With Fluent Validation, we get a very simple interface representing validating an input:

public interface IValidator<in T> {
    ValidationResult Validate(T instance);
}

Fluent Validation defines base classes for validators for a variety of scenarios:

public class CreateCustomerValidator: AbstractValidator<CreateCustomer> {
  public CreateCustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

We can then plug our validation to the pipeline as occurring before the main work to be done:

public class ValidatorHandler<TRequest, TResponse>
    : IRequestHandler<TRequest, TResponse>
    where TRequest : IRequest<TResponse> {

    private readonly IRequestHandler<TRequest, TResponse> _inner;
    private readonly IValidator<TRequest>[] _validators;
    
    public ValidatorHandler(IRequestHandler<TRequest, TResponse> inner,
        IValidator<TRequest>[] validators) {
        _inner = inner;
        _validators = validators;
    }

   public TResponse Handle(TRequest request) {
        var context = new ValidationContext(message);

        var failures = _validators
            .Select(v => v.Validate(context))
            .SelectMany(result => result.Errors)
            .Where(f => f != null)
            .ToList();

        if (failures.Any()) 
            throw new ValidationException(failures);

        return _inner.Handle(request);
   }
}

In our validation handler, we perform validation against Fluent Validation by loading up all of the matching validators. Because we have generic variance in C#, we can rely on the container to inject all validators for all matching types (base classes and interfaces). Having validators around messages means we can remove validation from our entities, and into contextual actions from a task-oriented UI.

Framework-less pipeline

We can now push a number of concerns into our application code instead of embedded as framework extensions. This includes things like:

  • Validation
  • Pre/post processing
  • Authorization
  • Logging
  • Auditing
  • Event dispatching
  • Notifications
  • Unit of work/transactions

Pretty much anything you’d consider to use a Filter in ASP.NET or Rails that’s more concerned with application-level behavior and not framework/transport specific concerns would work as a decorator in our handlers.

Once we have this approach set up, we can define our application pipeline as a series of decorators around handlers:

var handlerType = cfg.For(typeof (IRequestHandler<,>));

handlerType.DecorateAllWith(typeof (LoggingHandler<,>));
handlerType.DecorateAllWith(typeof (AuthorizationHandler<,>));
handlerType.DecorateAllWith(typeof (ValidatorHandler<,>));
handlerType.DecorateAllWith(typeof (PipelineHandler<,>));

Since this code is not dependent on frameworks or HTTP requests, it’s easy for us to build up a request, send it through the pipeline, and verify a response:

var handler = container.GetInstance<IHandler<CreateCustomer>>();

var request = new CreateCustomer {
    Name = "Bob"
};

var response = handler.Handle(request);

response.CreatedCustomer.Name.ShouldBe(request.Name);

Or if we just want one handler, we can test that one implementation in isolation, it’s really up to us.

By focusing on a uniform interface of one model in, one model out, we can define a series of patterns on top of that single interface for a variety of cross-cutting concerns. Our behaviors become less coupled on a framework and more focused on the real work being done.

All of this would be a bit easier if the underlying language supported this behavior. Since many don’t, we rely instead of translating these functional paradigms to OO patterns with IoC containers containing our glue.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Announcing Austin Code Camp 2014

Tue, 08/26/2014 - 22:35

It’s that time of year again to hold our annual Austin Code Camp, hosted by the Austin .NET User Group:

Austin 2014 Code Camp

We’re at a new location this year at New Horizons Computer Learning Center Austin, as our previous host can no longer host events. Big thanks to St. Edwards PEC for hosting us in the past!

Register for Austin Code Camp

We’ve got links on the site for schedule, registration, sponsorship, location, speaker submissions and more.

Hope to see you there!

And because I know I’m going to get emails…

Charging for Austin Code Camp? Get the pitchforks and torches!

In the past, Austin Code Camp has been a free event with no effective cap on registrations. We could do this because the PEC had a ridiculous amount of space and could accommodate hundreds of people. With free registration, we would see 50% drop-off attending from registrations. Not very fun to plan food with such uncertainty!

This year we have a good amount of space, but not infinite space. We can accommodate the typical number of people that come to our Code Camp (150-175), but for safety reasons we can’t put an unlimited cap on registrations as we’ve done in the past.

Because of this, we’re charging a small fee to reserve a spot. It’s not even enough to cover lunch or a t-shirt or anything, but it is a small enough fee to ensure that we’re fair to those that truly want to come.

Don’t worry though, if you can’t afford the fee, send me an email, and we can work it out.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Conventional HTML in ASP.NET MVC: Client-side templates

Thu, 08/14/2014 - 22:21

Other posts in this series:

In our last post, we brought everything together to build composable blocks of tags driven off of metadata. We did this to make sure that when a concept exists in our application, it’s only defined once and the rest of our system builds off of this concept. This reduces logic duplication across several layers, ensuring that we don’t have to “remember” to do repetitive tasks, like a required field needing an asterisk and data attributes.

All of this works great because we’ve got all the information at our disposal on the server-side, and we can push the completed product down to the client (browser). But what if we’re building a SPA, using Angular or Knockout or Ember or Backbone? Do we have to revert back to our old ways of duplication? Or can we have the best of both worlds?

There tend to be three general approaches:

  • Just hard code it and accept the duplication
  • Include metadata in your JSON API calls, through hypermedia or other means
  • Build intelligence into templates

I’ve done all three, and each have their benefits and drawbacks. Most teams I talk to go with #1, and some go with #2. Very few teams I meet even think about #3.

What I’d like to do is have the power of my original server-side Razor templates, with the strongly-typed views and intelligent expression-based helpers, but instead of complete HTML templates, have these be Angular views or Ember templates:

image

When we deliver our templates to the client as part of our SPA, we’ll serve up a special version of them, one that’s been parsed by our Razor engine. Normally, the Razor engine performs two tasks:

  • HTML generation
  • Binding model data

Instead, we’ll only generate our template, and the client will then bind the model to our template.

Serving templates, Ember style

Normally, the MVC view engine runs the Razor parser. But we’re not going that path, we’re going to parse the templates ourselves. The result of parsing will be placed inside our script tags. This part is a little long, so I’ll just link to the entire set of code.

HtmlHelperExtensions

A couple key points here. First, the part that runs the template through the view engine to render an HTML string:

builder.AppendLine("<script type=\"text/x-handlebars\" data-template-name=\"" + fullTemplateName + "\">");
var controllerContext = new ControllerContext(helper.ViewContext.HttpContext, new RouteData(), helper.ViewContext.Controller);
controllerContext.RouteData.Values["controller"] = string.IsNullOrEmpty(relativeDirName) ? "Home" : Path.GetDirectoryName(relativeDirName);
var result = ViewEngine.FindView(controllerContext, subtemplateName, null, false);
var stringWriter = new StringWriter(builder);
var viewContext = new ViewContext(controllerContext, result.View, new ViewDataDictionary(), new TempDataDictionary(), stringWriter);
result.View.Render(viewContext, stringWriter);

builder.AppendLine("</script>");

We render the view through our normal Razor view engine, but surround the result in a script tag signifying this is a Handlebars template. We’ll place the results in cache of course, as there’s no need to perform this step more than once. In our context objects we build up, we simply leave our ViewData blank, so that there isn’t any data bound to input elements.

We also make sure our templates are named correctly, using the folder structure to match Ember’s conventions. In our one actual MVC action, we’ll include the templates in the first request:

@Scripts.Render("~/bundles/ember")
@Scripts.Render("~/bundles/app")

@Html.Action("Enumerations", "Home")
@Html.RenderEmber()

Now that our templates are parsed and named appropriately, we can focus on building our view templates.

Conventional Handlebars

At this point, we want to use our HTML conventions to build out the elements needed for our Ember templates. Unfortunately, we won’t be able to use our previous tools to do so, as Ember uses Handlebars as its templating language. If we were using Angular, it might be a bit easier to build out our directives, but not by much. Client-side binding using templates or directives requires special syntax for binding to scope/model/controller data.

We don’t have our convention model, or even our HtmlTag library to use. Instead, we’ll have to use the old-fashioned way – building up a string by hand, evaluating rules as we go. I could have built a library for creating Ember view helpers, but it didn’t seem to be worth it in my case.

Eventually, I want to get to this:

@Html.FormBlock(m => m.FirstName)

But have this render this:

<div class="form-group">
    <label class="required control-label col-md-2"
       {{bind-attr for="view.firstName.elementId"}}>
       First Name
    </label>
    <div class="col-md-10">
        {{view TextField class="required form-control" 
               data-key="firstName" 
               valueBinding="model.firstName" 
               viewName="firstName" 
               placeholder="First"
        }}
    </div>
</div>

First, let’s start with our basic input and just cover the very simple case of a text field.

public static MvcHtmlString Input<TModel, TValue>(this HtmlHelper<TModel> helper,
    Expression<Func<TModel, TValue>> expression,
    IDictionary<string, object> htmlAttributes)
{
    var text = ExpressionHelper.GetExpressionText(expression).ToCamelCase();
    var modelMetadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
    var unobtrusiveAttributes = GetUnobtrusiveValidationAttributes(helper, expression);

    var builder = new StringBuilder("{{view");

    builder.Append(" TextField");

    if (unobtrusiveAttributes.ContainsKey("data-val-required"))
    {
        builder.Append(" class=\"required\"");
    }

    builder.AppendFormat(" data-key=\"{0}\"", text);

    builder.AppendFormat(" valueBinding=\"model.{0}\"", text);
    builder.AppendFormat(" viewName=\"{0}\"", text);

    if (!string.IsNullOrEmpty(modelMetadata.NullDisplayText))
        builder.AppendFormat(" placeholder=\"{0}\"", modelMetadata.NullDisplayText);

    if (htmlAttributes != null)
    {
        foreach (var item in htmlAttributes)
        {
            builder.AppendFormat(" {0}=\"{1}\"", item.Key, item.Value);
        }
    }

    builder.Append("}}");

    return new MvcHtmlString(builder.ToString());
}

We grab the expression text and model metadata, and begin building up our Handlebars snippet. We apply our conventions manually for each required attribute, including any additional attributes we need based on the MVC-style mode of passing in extra key/value pairs as a dictionary.

Once we have this in place, we can layer on our label helper:

public static MvcHtmlString Label<TModel, TValue>(
    this HtmlHelper<TModel> helper, 
    Expression<Func<TModel, TValue>> expression)
{
    var text = ExpressionHelper.GetExpressionText(expression);
    var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
    var unobtrusiveAttributes = GetUnobtrusiveValidationAttributes(helper, expression);

    var builder = new StringBuilder("<label ");
    if (unobtrusiveAttributes.ContainsKey("data-val-required"))
    {
        builder.Append(" class=\"required\"");
    }
    builder.AppendFormat(" {{{{bind-attr for=\"view.{0}.elementId\"}}}}", text.ToCamelCase());
    builder.Append(">");

    string labelText = metadata.DisplayName ?? (metadata.PropertyName == null
        ? text.Split(new[] {'.'}).Last()
        : Regex.Replace(metadata.PropertyName, "(\\B[A-Z])", " $1"));

    builder.Append(labelText);
    builder.Append("</label>");

    return new MvcHtmlString(builder.ToString());
}

It’s very similar to the code in the MVC label helper, with the slight tweak of defaulting label names to the property names with spaces between words. Finally, our input block combines these two together:

public static MvcHtmlString FormBlock<TModel, TValue>(
    this HtmlHelper<TModel> helper,
    Expression<Func<TModel, TValue>> expression)
{
    var builder = new StringBuilder("<div class='form-group'>");
    builder.Append(helper.Label(expression));
    builder.Append(helper.Input(expression));
    builder.Append("</div>");
    return new MvcHtmlString(builder.ToString());
}

Now, our views start to become a bit more sane, and it takes a keen eye to see that it’s actually a Handlebars template. We still get strongly-typed helpers, metadata-driven elements, and synergy between our client-side code and our server-side models:

@model MvcApplication.Models.AccountCreateModel
{{title 'Create account'}}

<form {{action 'create' on='submit'}}>
    <fieldset>
        <legend>Account Information</legend>
        @Html.FormBlock(m => m.Username)
        @Html.FormBlock(m => m.Password)
        @Html.FormBlock(m => m.ConfirmPassword)
    </fieldset>

We’ve now come full-circle, leverage our techniques that let us be ultra-productive building out pages on the server side, but not losing that productivity on the client-side. A concept such as “required field” lives in exactly one spot, and the rest of our system reads and reacts to that information.

And that, I think, is pretty cool.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Conventional HTML in ASP.NET MVC: Building larger primitives

Fri, 07/25/2014 - 16:52

Other posts in this series:

We’ve taken our individual form elements quite far now, adopting a variety of conventions in our output to remove the boring, duplicated code around deciding how to display those individual elements. We have everything we need to extend and alter the conventions around those single elements.

And that’s a good thing – we want to keep using those primitives around individual elements. But what if we peeked a little bit larger? Are there larger common patterns in play that we can start incorporating? Let’s look at the basic input template, from Bootstrap:

<div class="form-group">
    @Html.Label(m => m.Password)
    <div class="col-md-10">
        @Html.Input(m => m.Password)
        @Html.ValidationMessageFor(m => m.Password, ""
          , new { @class = "text-danger" })
    </div>
</div>

Starting with the most basic element, the input tag, let’s look at gradually increasing scope of our building block:

  • Input
  • Input and validation
  • Input, validation in a div
  • Label and the div input
  • Form group

The tricky part here is that at each level, I want to be able to affect the resulting tags, some or all. Our goal here is to create building blocks for each level, so that we can establish a set of reusable components with sensible defaults along the way. This is a similar exercise as building a React class or Angular directive – establish patterns early and standardize your approach.

From the above list of items, I’ll likely only want to create blocks around increasing scopes of DOM elements, so let’s whittle this down to 3 elements:

  • Input
  • Input Block
  • Form Block

We already have our original Input method, let’s create the first input block.

Basic input block

Because we have our HtmlTag primitive, it’s trivial to combine elements together. This is a lot easier than working with strings or MvcHtmlStrings or the less powerful TagBuilder primitive. We’ll return the outer div tag, but we still need ways of altering the inner tags. This includes the Label, the Input, and Validator. Here’s our input block:

public static HtmlTag InputBlock<T>(this HtmlHelper<T> helper,
    Expression<Func<T, object>> expression,
    Action<HtmlTag> inputModifier = null,
    Action<HtmlTag> validatorModifier = null) where T : class
{
    inputModifier = inputModifier ?? (_ => { });
    validatorModifier = validatorModifier ?? (_ => { });

    var divTag = new HtmlTag("div");
    divTag.AddClass("col-md-10");

    var inputTag = helper.Input(expression);
    inputModifier(inputTag);

    var validatorTag = helper.Validator(expression);
    validatorModifier(validatorTag);

    divTag.Append(inputTag);
    divTag.Append(validatorTag);

    return divTag;
}

We create an Action<HtmlTag> for the input/validator tags. If someone wants to modify those two elements directly, instead of wonky anonymous-objects-as-dictionaries, we allow them full access to the tag via a callback, similar to jQuery. Next, we default those two modifiers to no-op if they are not supplied.

We then build up our input block, which consists of the outer div with the input tag and validator tag as children. In our view, we can replace the input block:

<div class="form-group">
    @Html.Label(m => m.Email)
    @Html.InputBlock(m => m.Email)
</div>
<div class="form-group">
    @Html.Label(m => m.Password)
    <div class="col-md-10">
        @Html.Input(m => m.Password)
        @Html.Validator(m => m.Password)
    </div>
</div>

Just to contrast, I included the non-input-blocked version. Now that we have this piece, let’s look at building the largest primitive, the form block.

Form input block

In the same tradition of Angular directives, React classes and Ember views, we can build larger components out of smaller ones, reusing the smaller components as necessary. This also ensures our larger component automatically picks up changes from the smaller ones. Here’s our FormBlock method:

public static HtmlTag FormBlock<T>(this HtmlHelper<T> helper,
    Expression<Func<T, object>> expression,
    Action<HtmlTag> labelModifier = null,
    Action<HtmlTag> inputBlockModifier = null,
    Action<HtmlTag> inputModifier = null,
    Action<HtmlTag> validatorModifier = null
    ) where T : class
{
    labelModifier = labelModifier ?? (_ => { });
    inputBlockModifier = inputBlockModifier ?? (_ => { });

    var divTag = new HtmlTag("div");
    divTag.AddClass("form-group");

    var labelTag = helper.Label(expression);
    labelModifier(labelTag);

    var inputBlockTag = helper.InputBlock(
        expression, 
        inputModifier, 
        validatorModifier);
    inputBlockModifier(inputBlockTag);

    divTag.Append(labelTag);
    divTag.Append(inputBlockTag);

    return divTag;
}

It’s very similar to our input block method, where we provide defaults for our initializers, create the outer div tag, build the child tags, apply child modifiers, and append those child tags to the outer div. Going back to our view, it becomes quite simplified:

@Html.FormBlock(m => m.Email)
@Html.FormBlock(m => m.Password)
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <div class="checkbox">
            @Html.Input(m => m.RememberMe).RemoveClasses()
            @Html.Label(m => m.RememberMe).RemoveClasses()
        </div>
    </div>
</div>

We have one outlier, our “remember me” checkbox, which I try to avoid at all costs. Let’s look at a couple of other examples. Here’s our register view:

@Html.ValidationSummary("", new { @class = "text-danger" })
@Html.FormBlock(m => m.Email)
@Html.FormBlock(m => m.Password)
@Html.FormBlock(m => m.ConfirmPassword)
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" class="btn btn-default" value="Register" />
    </div>
</div>

And here’s our reset password view:

@Html.ValidationSummary("", new { @class = "text-danger" })
@Html.Input(m => m.Code)
@Html.FormBlock(m => m.Email)
@Html.FormBlock(m => m.Password)
@Html.FormBlock(m => m.ConfirmPassword)
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" class="btn btn-default" value="Reset" />
    </div>
</div>

Much more simplified, with conventions around the individual input elements and HtmlHelper extensions around larger blocks. I would likely go an additional step and create an HtmlHelper extension around the buttons as well, since Bootstrap buttons have a very predictable, standardized set of HTML to build out.

We’ve removed a lot of our boilerplate HTML, but still allowed customization as needed. We also still expose the smaller components through InputBlock and Input, so that if the HTML varies a lot we can still keep the smaller building blocks. There’s still a bit of magic going on, but it’s only a click away to see what “FormBlock” actually does. Finally, what conventions really allow us to do is stop focusing on the minutiae of the HTML we have to include on every display/input block of HTML.

We remove bike shedding arguments and standardize our approach, allowing us to truly hone in on what is interesting, challenging or different. This is the true power of conventions – stop pointless and wasteful arguments about things that truly don’t matter through a standardized, but extensible, approach built on conventions.

In our next (and final) post, we’ll look at how we can extend these approaches for client-side templates built in Angular, Ember and more.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Conventional HTML in ASP.NET MVC: Validators

Thu, 07/24/2014 - 20:33

Other posts in this series:

We’re marching towards our goal of creating conventional components, similar to React classes or Angular directives, but there’s one last piece we need to worry about before we get there: validators.

Validators can be a bit tricky, since they largely depend on the validation framework you’re trying to use. My validation framework of choice is still Fluent Validation, but you can use others as well. Since the data annotation validators are fairly popular, this example will use that as the starting point.

First, we have to figure out what our validation HTML should look like, and how it should affect the rest of our output. But we don’t have a “Validator” convention, we only have “Label”, “Editor”, and “Display” as our possibilities.

Luckily, underneath the covers these Label etc. conventions are only categories of elements, and we can easily create a new category of conventions for our own purposes. The Label/Editor/Display properties are only convenience methods. In our base convention class, let’s create a new category of conventions via a similar property:

public class OverrideHtmlConventions : DefaultHtmlConventions
{
    protected ElementCategoryExpression Validators
    {
        get
        {
            var builderSet = Library
                .For<ElementRequest>()
                .Category("Validator")
                .Defaults;
            return new ElementCategoryExpression(builderSet);
        }
    }

    public OverrideHtmlConventions()
    {
        Editors.Always.AddClass("form-control");
        Labels.Always.AddClass("control-label");
        Labels.Always.AddClass("col-md-2");

This will allow us to append additional conventions to a Validator category of element requests. With a custom builder, we can create a default version of our validator span (without any validation messages):

public class SpanValidatorBuilder : IElementBuilder
{
    public HtmlTag Build(ElementRequest request)
    {
        return new HtmlTag("span")
            .AddClass("field-validation-error")
            .AddClass("text-danger")
            .Data("valmsg-for", request.ElementId);
    }
}

And add it to our default conventions:

public OverrideHtmlConventions()
{
    Validators.Always.BuildBy<SpanValidatorBuilder>();

    Editors.Always.AddClass("form-control");
    Labels.Always.AddClass("control-label");
    Labels.Always.AddClass("col-md-2");

The last part is actually generating the HTML. We need to do two things -

  • Determine if the current field has any validation errors
  • If so, build out the tag with the correct error text

The first part is actually fairly straightforward – ha ha just kidding, it’s awful. Getting validation messages out of ASP.NET MVC isn’t easy, but the source is available so we can just copy what’s there.

public static HtmlTag Validator<T>(this HtmlHelper<T> helper,
    Expression<Func<T, object>> expression) where T : class
{
    // MVC code don't ask me I just copied
    var expressionText = ExpressionHelper.GetExpressionText(expression);
    string fullHtmlFieldName 
        = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expressionText);

    if (!helper.ViewData.ModelState.ContainsKey(fullHtmlFieldName))
        return new NoTag();

    ModelState modelState = helper.ViewData.ModelState[fullHtmlFieldName];
    ModelErrorCollection modelErrorCollection = modelState == null 
        ? null 
        : modelState.Errors;
    ModelError error = modelErrorCollection == null || modelErrorCollection.Count == 0 
        ? null 
        : modelErrorCollection.FirstOrDefault(m => !string.IsNullOrEmpty(m.ErrorMessage)) 
        ?? modelErrorCollection[0];
    if (error == null)
        return new NoTag();
    // End of MVC code

    var tagGeneratorFactory = DependencyResolver.Current.GetService<ITagGeneratorFactory>();
    var tagGenerator = tagGeneratorFactory.GeneratorFor<ElementRequest>();
    var request = new ElementRequest(expression.ToAccessor())
    {
        Model = helper.ViewData.Model
    };

    var tag = tagGenerator.Build(request, "Validator");

    tag.Text(error.ErrorMessage);

    return tag;
}

Ignore what’s going on in the first section – I just grabbed it from the MVC source. The interesting part is at the bottom, where I grab a tag generator factory, create a tag generator, and build an HtmlTag using the Validator category for the given ElementRequest. This is what our Label/Editor/Display methods do underneath the covers, so I’m just emulating their logic. It’s a bit clunkier than I want, but I’ll amend that later.

Finally, after building the base validator tag, we set the inner text to the error message we determined earlier. We only use the first error message – too many and it becomes difficult to read. The validation summary can still be used for multiple errors. Our view is now:

<div class="form-group">
    @Html.Label(m => m.Email)
    <div class="col-md-10">
        @Html.Input(m => m.Email)
        @Html.Validator(m => m.Email)
    </div>
</div>
<div class="form-group">
    @Html.Label(m => m.Password)
    <div class="col-md-10">
        @Html.Input(m => m.Password)
        @Html.Validator(m => m.Password)
    </div>
</div>

Since we know that every validation message will need that “text-danger” class applied, applying it once to our conventions means that we’ll never have to copy-paste that portion around ever again. And much easier to develop against than the MVC templates, which quite honestly, are quite difficult to develop against.

We could go a step further and modify our Label conventions to pick up on the “Required” attribute and show an asterisk or bold required field labels.

Now that we have quite a bit of consistency in our groups of form elements, in the next post we’ll look at tackling grouping multiple tags into a single input/form component.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs