Showpitch Advanced Part 3: Using Neat Architecture for Validation

Last week we reviewed using Neat Architecture for Showpitch‘s Logging. This week we’re going to go in to Neat and Validation on Showpitch.

We’re all familiar with the need for Validation when building an application. Maybe there’s a property that should be an email, or maybe there’s an integer that should always be below a certain amount. In any given application there’s going to be a lot of these Validation concerns that come up. And just as with Logging we’re going to end up writing a lot of the same code, over and over again, unless there’s a better way.

Validation, Over and Over

Lets look at a typical Validation scenario:

public class Thing
{
    public string ThingAMaJig { get; set; }
    public int ThingAMaBob { get; set; }
}

public class AThingAddingClass : IAThingAddingClass
{
    private readonly IThingRepository _thingRepository;
    
    public AThingAddingClass(IThingRepository thingRespository)
    {
        _thingRepository = thingRepository;
    }
    
    public void AddANewThing(Thing aThing)
    {
        if(aThing.ThingAMaJig == null)
        {
            throw new ValidationException("ThingAMaJig Required!");
        }
        _thingRepository.Save(aThing);
    }
}

That’s really simple, but now imagine writing this out each time you’re going to do anything with that Thing, and then extrapolate that out to hundreds of times in every application, for all of the properties you’re going to validate! Consider:

public class AThingAddingClass : IAThingAddingClass
{
    private readonly IThingRepository _thingRepository;
    
    public AThingAddingClass(IThingRepository thingRespository)
    {
        _thingRepository = thingRepository;
    }
    
    public void AddANewThing(Thing aThing)
    {
        if(aThing.ThingAMaJig == null)
        {
            throw new ValidationException("ThingAMaJig Required!");
        }
        _thingRepository.Save(aThing);
    }
    
    public void UpdateAThing(Thing aThing)
    {
        if(aThing.ThingAMaJig == null)
        {
            throw new ValidationException("ThingAMaJig Required!");
        }
        _thingRepository.Update(aThing);
    }
    
    public void IndexAThing(Thing aThing)
    {
        if(aThing.ThingAMaJig == null)
        {
            throw new ValidationException("ThingAMaJig Required!");
        }
        _thingRepository.Index(aThing);
    }
    
    public void DefaultAThing(Thing aThing)
    {
        if(aThing.ThingAMaJig == null)
        {
            throw new ValidationException("ThingAMaJig Required!");
        }
        aThing.ThingAMaBob = 7;
        _thingRepository.Save(aThing);
    }
}

Things are already starting to get out of hand!

Validation, A Validator For Every Object

So we can start to address this issue with a new object, specifically one that validates that Thing for us:

public class AThingValidatingClass : IAThingValidatingClass
{
    public void ValidateAThing(Thing aThing)
    {
        if(aThing.ThingAMaJig == null)
        {
            throw new ValidationException("ThingAMaJig Required!");
        }
    }
}

Let’s try using this in the previous out of control example:

public class AThingAddingClass : IAThingAddingClass
{
    private readonly IThingRepository _thingRepository;
    private readonly IAThingValidatingClass _aThingValidatingClass;
    
    public AThingAddingClass(IThingRepository thingRespository, IAThingValidatingClass aThingValidatingClass)
    {
        _thingRepository = thingRepository;
        _aThingValidatingClass = aThingValidatingClass;
    }
    
    public void AddANewThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        _thingRepository.Save(aThing);
    }
    
    public void UpdateAThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        _thingRepository.Update(aThing);
    }
    
    public void IndexAThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        _thingRepository.Index(aThing);
    }
    
    public void DefaultAThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        aThing.ThingAMaBob = 7;
        _thingRepository.Save(aThing);
    }
}

Well that certainly shortens things up. But we still have a couple of issues here. First, we’d now have to develop a Validator for every object we want to Validate. Second, we seem to have more than one responsibility in our methods now. Before our methods just did something with a Thing, but now they validate a Thing and then do something with it.

Validation, A Validator and a Decorator For Every Object Then

So lets address the second issue first. We could separate the responsibilities, just like with Logging, using a Decorator:

public class AThingAddingClass : IAThingAddingClass
{
    private readonly IThingRepository _thingRepository;
    
    public AThingAddingClass(IThingRepository thingRespository)
    {
        _thingRepository = thingRepository;
    }
    
    public void AddANewThing(Thing aThing)
    {
        _thingRepository.Save(aThing);
    }
    
    public void UpdateAThing(Thing aThing)
    {
        _thingRepository.Update(aThing);
    }
    
    public void IndexAThing(Thing aThing)
    {
        _thingRepository.Index(aThing);
    }
    
    public void DefaultAThing(Thing aThing)
    {
        aThing.ThingAMaBob = 7;
        _thingRepository.Save(aThing);
    }
}

public class AThingAddingClassValidationDecorator : IAThingAddingClass
{
    private readonly IAThingAddingClass _aThingAddingClass;
    private readonly IAThingValidatingClass _aThingValidatingClass;
    
    public AThingAddingClass(IAThingAddingClass aThingAddingClass, IAThingValidatingClass aThingValidatingClass)
    {
        _aThingAddingClass = aThingAddingClass;
        _aThingValidatingClass = aThingValidatingClass;
    }
    
    public void AddANewThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        _aThingAddingClass.AddANewThing(aThing);
    }
    
    public void UpdateAThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        _aThingAddingClass.UpdateAThing(aThing);
    }
    
    public void IndexAThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        _aThingAddingClass.IndexAThing(aThing);
    }
    
    public void DefaultAThing(Thing aThing)
    {
        _aThingValidatingClass.ValidateAThing(aThing);
        aThing.ThingAMaBob = 7;
        _aThingAddingClass.DefaultAThing(aThing);
    }
}

So now we only have one responsibility per method, but we still have the issue of having to build a Validator for each object. And on top of that, now we have to build a Decorator for each object as well!

Validation, A Better Way

Just as when we reviewed Logging, we know there’s a better way using interceptors. But how can we build something so generic for Validation?

Luckily for us, .Net has had a solution available for quite a while in the form of System.ComponentModel.DataAnnotations. These have been used in ASP.Net MVC for quite a while, but we can leverage them to build a Validation interceptor in to Neat, and we have!

Using System.ComponentModel.DataAnnotations we can declare how to Validate each property right on that property! So now our Thing becomes:

using System.ComponentModel.DataAnnotations;

public class Thing
{
    [Required]
    public string ThingAMaJig { get; set; }
    public int ThingAMaBob { get; set; }
}

From here, our Validation interceptor can pick up any of a large number of System.ComponentModel.DataAnnotations and Validate the value in the property based on them. We’ve built the rest of that in to the ApplicationProcessing interceptor in Neat, by way of an ApplicationProcessingRule for Validation. You can take a look at the objects that leverage this for yourself in Neat:

  • Neat.Infrastructure.Unity.Interceptor.ApplicationProcessingInterceptor
  • Neat.Infrastructure.Unity.ApplicationProcessing.ApplicationProcessor
  • Neat.Infrastructure.Unity.ApplicationProcessing.IApplicationProcessingRule
  • Neat.Infrastructure.Validation.ApplicationProcessing.ValidationApplicationProcessingRule
  • Neat.Model.NeatExample

This leaves us with a much simpler and more concise class than any of the other options, without having to build a Decorator ourselves:

public class AThingAddingClass : IAThingAddingClass
{
    private readonly IThingRepository _thingRepository;
    
    public AThingAddingClass(IThingRepository thingRespository)
    {
        _thingRepository = thingRepository;
    }
    
    public void AddANewThing(Thing aThing)
    {
        _thingRepository.Save(aThing);
    }
    
    public void UpdateAThing(Thing aThing)
    {
        _thingRepository.Update(aThing);
    }
    
    public void IndexAThing(Thing aThing)
    {
        _thingRepository.Index(aThing);
    }
    
    public void DefaultAThing(Thing aThing)
    {
        aThing.ThingAMaBob = 7;
        _thingRepository.Save(aThing);
    }
}

But how do you implement the System.ComponentModel.DataAnnotations for Validation? Lets look at an example:

public class ValidationResponse
{
    public ValidationResponse()
    {
        ValidationErrors = new List();
        IsValid = true;
    }
    
    public bool IsValid { get; set; }
    public List ValidationErrors { get; set; }
    
}

// SNIP!
private ValidationResponse Validate(object objectToValidate)
{
    var validationResponse = new ValidationResponse();
    var results = new List();
    if (!Validator.TryValidateObject(objectToValidate, new System.ComponentModel.DataAnnotations.ValidationContext(objectToValidate), results, true))
    {
        validationResponse.IsValid = false;
        validationResponse.ValidationErrors.AddRange(results.Select(validationResult => validationResult.ErrorMessage));
    }
    
    return validationResponse;
}
// SNIP!

That’s it!

Validation can quickly become a lot of work in an application, but by using Neat, especially the Validation interceptor and System.ComponentModel.DataAnnotations Validation can be added in to an application quickly and easily. We’ve used this Validation at Showpitch to very quickly spin up new Domain Objects and make them available for use while protecting the data from invalid inputs and states. It has saved and will continue to save hours of work for Showpitch!

Would you like to know more about something I’ve written about, or do you want to see me cover something in the next post? Are there parts of Neat or Showpitch you’d like to learn more about? Please comment below! And check back for more!

<< Back to Showpitch Advanced Part 2

Advertisement

Showpitch Advanced Part 1: Using Neat Architecture for Domain Services

After 3 weeks of high level review of Showpitch we’re going to dive in to more advanced topics. This week we’re going to cover the specifics of using Neat Architecture for Showpitch.

Neat Architecture

Showpitch uses the Neat Architecture to allow for very rapid development and a great amount of flexibility and power. You can find the Neat Architecture in practice on GitHub, so check it out when you have a chance! Now let’s get in to what Neat Architecture is.

Neat Components

Neat starts with several important components, all from NuGet:

  • ASP.Net Web Api
    • Microsoft.AspNet.Cors.5.2.3
    • Microsoft.AspNet.WebApi.5.2.3
    • Microsoft.AspNet.WebApi.Client.5.2.3
    • Microsoft.AspNet.WebApi.Core.5.2.3
    • Microsoft.AspNet.WebApi.Cors.5.2.3
    • Microsoft.AspNet.WebApi.Tracing.5.2.3
    • Microsoft.AspNet.WebApi.WebHost.5.2.3
  • Microsoft Practices Unity 3
    • CommonServiceLocator.1.3
    • Unity.3.5.1404.0
    • Unity.Interception.3.5.1404.0
    • Unity.WebAPI.5.1
  • OData
    • Microsoft.AspNet.WebApi.OData.5.5.1
    • Microsoft.Data.Edm.5.6.0
    • Microsoft.Data.OData.5.6.0
    • System.Spatial.5.6.0
  • NLog
    • NLog.4.0.1
    • NLog.MongoDB.0.7.0
    • mongocsharpdriver.1.8.3
  • JSON.Net
    • Newtonsoft.Json.6.0.4
    • Newtonsoft.Json.7.0.1
  • Octopack
    • OctoPack.3.0.42
  • MongoRepository
    • MongoRepository.1.6.8
    • mongocsharpdriver.1.10.0

Neat Solution Structure

The Solution Structure is comprised of a pretty traditional N-Tier stack. This stack is broken out in to a few more layers to facilitate further decoupling and reduce friction among components.

  • Neat.Model – All Domain Models
  • Neat.Data – Common Data Access Definition
  • Neat.Data.Mongo – Mongo Data Access Implementation
  • Neat.Infrastructure – Components for Application Functionality
  • Neat.Application – Core Business Logic
  • Neat.Service – Orchestration of Business Logic Components
  • Neat.Infrastructure.WebApi – Web Api Specific Functional Components
  • Neat.Web.Api – Web Api Host

A Closer Look at Unity and IoC in Neat

In Neat we use a class called Bootstrapper in each project to configure all Type Registrations for that project. We then expose an Attach method in each Bootstrapper, allowing components that rely on that project to run that project’s configuration against that component’s Unity container. Here’s an example:

public static class Bootstrapper
{
    public static void Register()
    {
        var container = new UnityContainer();

        Register(container);
    }

    public static void Attach(IUnityContainer container)
    {
        Register(container);
    }

    private static void Register(IUnityContainer container)
    {
        Neat.Data.Mongo.Bootstrapper.Attach(container);
        Neat.Infrastructure.Bootstrapper.Attach(container);

        container.RegisterType(typeof (IDomainApplication<>),
            typeof (DomainApplication<>),
            new ContainerControlledLifetimeManager());

        container.RegisterAllService<IApplication>();
    }
}

There’s a lot happening in this code:

  • The Attach Method – Components that depend on this one pass their container in here so that this component can register its classes on the same container
  • The Two Attach Calls – This component in turn calls Attach on the components it depends on
  • The typeof Registrations – This is how to register the generic implementation so that any type passed to the generic results in a resolvable type. Using this registration pattern throughout the stack these components can handle any domain object from the Web Api through to the Database
  • RegisterAllService – This is an Unity Extension in Neat that registers every class as the default registration for its other interfaces when it has the marker interface specified
  • ContainerControlledLifetimeManager – This lifetime manager ensures that the type registered is resolved as a Singleton

A Closer Look at the Web Api Controller in Neat

The Controllers in Neat use the generic Domain stack to expose the Domain Models. Here’s an example:

public class NeatController : BaseReadWriteDeleteController<NeatExample>
{
    public NeatController(IDomainService<NeatExample> domainService)
        : base(domainService)
    {}
}

As you can see, using the Unity registration from before and this Controller pattern, we’re able to rapidly expose Api Services for new Domain Models. But where are the methods? The answer lies in the BaseReadWriteDeleteController:

public class BaseReadWriteDeleteController<T> : BaseApiController where T : class, IEntity<string>, new()
{
    private readonly IDomainService<T> _domainService;

    public BaseReadWriteDeleteController(IDomainService<T> domainService)
    {
        _domainService = domainService;
    }

    // GET api/{T}
    [EnableQuery]
    public IQueryable<T> Get()
    {
        return _domainService.GetAll();
    }

    // GET api/{T}/{id}
    public T Get(string id)
    {
        return _domainService.GetById(id);
    }

    // POST api/{T}
    public void Post([FromBody]T entity)
    {
        _domainService.Add(entity);
    }

    // PUT api/{T}
    public void Put([FromBody]T entity)
    {
        _domainService.Update(entity);
    }

    // DELETE api/{T}/{id}
    public void Delete(string id)
    {
        _domainService.Delete(id);
    }

    // GET api/{T}/getempty
    [HttpGet]
    public T GetEmpty()
    {
        return new T();
    }
}

This pattern works very well with MongoRepository due to its generic implementation. Perhaps in a future post we’ll cover an Entity Framework Code First approach for this.

This architecture allows for very rapid application development. To add a new Domain Service to this stack the steps are simply:

  1. Add a new Domain Model
  2. Add a new Controller and inherit from the appropriate Base Controller with the right methods
  3. Profit!

In future posts we’ll cover how to add additional behavioral capabilities in to this architecture and extend it with other service features. Is there a specific part of this architecture that you have questions about? Is there another part of Neat you saw on GitHub that you want me to write about next? Please leave a comment below to let me know! And keep checking back for more info about Showpitch and Neat!

<< Back to Showpitch 103
On to Showpitch Advanced Part 2 >>

Showpitch 103: Our Cloud Ecosystem and Our Platform

Last week we reviewed the technology we’re using to build Showpitch. This week we’re going to present the ecosystem that has emerged from that technology and what the Showpitch Platform looks like as a result.

Let’s start by breaking down the ecosystem at a high level:

  • Showpitch Core
    • Platform Application Stack
    • Configuration Service
    • Agent Services
    • Service Manager
    • Administrative Service
  • Consumer Services
  • Business Services
  • Clients
    • Web Clients
    • App Clients
    • 3rd Party Clients
  • Media Stack
    • Repository
    • Connectors
    • Distribution Channel Partners

Taken together this comprises the Showpitch Ecosystem from a very high level. An immediate take away here is that Showpitch is more than just a website. What we’ve built is a full platform.

Further, as covered in the prior post, this ecosystem lives in the cloud, implemented on top a variety of cloud technologies, service providers, and partners.

So let’s get into the details for each of the components of this ecosystem.

Showpitch Core

This is, as the name implies, the core of Showpitch. That is, many of the other components of the Showpitch Ecosystem rely on this core, leveraging the business logic implemented within to drive business processes and provide services.

Platform Application Stack

The Platform Application Stack contains the aforementioned business logic for Showpitch. Any request that passes through the Showpitch Platform subsequently uses this component to determine what to do or how to do it.

Configuration Service

The Configuration Service takes typical application configuration to another level. With this service configuration across application components, and even environments, can be shared while allowing settings to be specified for individual application instances. Further, the Configuration Service allows settings to be updated without having to redeploy application components, meaning the behavior in and across Production can be changed from a simple Management UI and take effect without impacting Production service.

Agent Services

Agent Services are vital to the performance of Showpitch. Agent Services off load the work from the platform services, allowing the heavy lifting for long running tasks, or large task sets, to run “in the background” without taking up processing and memory resources from the real time services that Showpitch provides. Agent Services also allow for multi step work flows to be executed, which enables much more complex business logic to run on the Showpitch Platform.

Service Manager

The Service Manager is the other half to the Agent Services. While the Agent Services perform all the background processing and work flow for the Showpitch Platform, the Service Manager allows control of the Agent Services. It handles monitoring, stopping, starting, updating, and deploying the Agent Services. One of the most interesting features built into the management of Agent Services is that they can be newly configured or reconfigured using the Configuration Service, and then spun up in multiple instances across the same machine or multiple machines, which allows for horizontal scaling to handle load.

Administrative Service

The Administrative Service puts management capabilities directly into the hands of the Business Owners. CMS Tools, Item Lists, and Advertisement Managers, among others, allow the Business greater control over the content presented on Showpitch.com. This is important for maintaining the messaging the Business wants to put forward on the site.

Consumer Services & Business Services

The Consumer and Business Services are provided by the Showpitch API. This API provides all functionality for the Showpitch Platform. For instance, the API is what provides all the functionality for the Showpitch.com Web Client. It’s also used by the Administrative Service and for many of Showpitch‘s internal systems. This API serves both Consumers of the Showpitch Platform and Business integration partners, like Joint Venture Partners and Media Distribution Partners.

Clients

The Showpitch Platform has, and will have, many different types of Clients.

Web Clients

The most obvious example of a Web Client is Showpitch.com. Other Web Clients are planned in the future. Web Clients communicate with the Showpitch Platform via the API, as a Consumer of the Platform. Through these Clients Users can interact with Showpitch through any modern browser, including on desktops, tablets, and mobile devices.

App Clients

In addition to Clients on the Web Showpitch also supports native App Clients, on any type of device that can consume a REST API, which includes just about every device out there. App Clients aren’t simply restricted to native Mobile Apps either, but can potentially include Desktop Applications, Game Console Applications, TV Applications, and even IoT devices.

3rd Party Clients

3rd Party Clients include other platforms and systems that consume services from Showpitch. These Clients may consume both Consumer and Business services from the Showpitch Platform.

Media Stack

Of special note among the Consumer and Business services available on the Showpitch Platform are services related to Media. These are of such great import that they’ve been separated from the rest of platform and given their own domain.

Repository

The core of the Showpitch Media Stack is the Media Repository. This is where all Media provided to Showpitch resides, regardless of how it was provided. Without this store, there’d be no Media to consume. This Repository is provided by a combination of JW Platform and Cloud Files. The Repository is secured, requiring authorization from the Showpitch Platform to gain access.

Connectors

Where the Repository provides for storage of the Media on Showpitch, Connectors allow for access to this Media. As mentioned previously, access to the Media is secured, requiring authorization from the Showpitch Platform to gain access. The Connectors all integrate with this authorization scheme, allowing for various types of access to the Media depending on the Connector and the authorization available. This can include viewing the Media, downloading the Media, or even uploading or changing the Media.

Distribution Channel Partners

If the Repository is the store for the Media, and the Connectors provide access to it, then the purpose of the Distribution Channel Partners is to provide Media to Showpitch or distribute the Media available on Showpitch to various platforms and channels. The first Distribution Channel Partner we have is Showpitch.com itself. Here one can browse the Media on Showpitch, upload new Media to the platform, view the Media directly, and download it as well.

This sums up the Showpitch Ecosystem from a high level. Over several future posts we’ll start to dive in to each part of the ecosystem, providing specific stories of implementation within these components. Is there a part of the ecosystem you want me to cover first? If so please leave a comment below. And keep checking back!

<< Back to Showpitch 102
On to Showpitch Advanced Part 1 >>

Knockout + Web API + SignalR = Awesomeness

This blog post is based on an excellent video by Brad Wilson delivered at this year’s NDC. It’s a walk-through of how to quickly build a real time web application, in this case a To Do List application, using Knockout, Web API, and SignalR.

You can find the example code on GitHub – https://github.com/bradwilson/ndc2012.

This video covers using the following technologies to build a truly awesome application quickly:

The idea here is that there is a clear separation between the client and the server. The client runs as an MVVM application written in javascript. Specifically written in Knockout in this case.

Then, to provide communication between the client and the server there are two options, Web API and SignalR.

Web API provides the ability to build a RESTful interface for the client to communicate with. SignalR provides a full duplex connection, over websockets, or emulates one using graceful degradation.

In the video Brad talks about using Web API to make changes to the application state and then pushing those changes out to any clients concerned with the change. This uses the full duplex communication that SignalR provides.

Looking at the code it can be seen how this is accomplished. By making the Hubs from SignalR available to the Web API Controller the response can be pushed out over the Hub to all of the Clients –


public class ToDoController : ApiControllerWithHub<ToDoHub>
{
private static List<ToDoItem> db = new List<ToDoItem>
{
new ToDoItem { ID = 0, Title = "Do a silly demo on-stage at NDC" },
new ToDoItem { ID = 1, Title = "Wash the car" },
new ToDoItem { ID = 2, Title = "Get a haircut", Finished = true }
};
private static int lastId = db.Max(tdi => tdi.ID);

public HttpResponseMessage PostNewToDoItem(ToDoItem item)
{
lock (db)
{
// Add item to the "database"
item.ID = Interlocked.Increment(ref lastId);
db.Add(item);
// Notify the connected clients
Hub.Clients.addItem(item);
// Return the new item, inside a 201 response
var response = Request.CreateResponse(HttpStatusCode.Created, item);
string link = Url.Link("apiRoute", new { controller = "todo", id = item.ID });
response.Headers.Location = new Uri(link);
return response;
}
}

}

From the Client it can be seen that the Knockout observable then receives the update from the SignalR Client rather than from the response to the RESTful call –


self.sendCreate = function () {
$.ajax({
url: "/api/todo",
data: { 'Title': self.addItemTitle(), 'Finished': false },
type: "POST"
});
self.addItemTitle("");
};

hub.addItem = function (item) {
viewModel.add(item.ID, item.Title, item.Finished);
};

Notice how easy it is to get a real time application communicating changes to a number of Clients. One final thing to consider is how easy it is to update the view in the client with the data coming back over this connection –


<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>NDC Demo</title>
<link rel="shortcut icon" href="favicon.ico" />
<link rel="stylesheet" type="text/css" href="css/site.css" />
</head>
<body>
<form data-bind="submit: sendCreate">
<label for="title">Add a task:</label>
<input type="text" name="title" id="title" data-bind="value: addItemTitle, valueUpdate: 'afterkeydown'" />
<input type="submit" title="Add a new item" value="Add" disabled="disabled" data-bind="enable: addItemTitle().length > 0" />
</form>
<section data-bind="visible: items().length > 0" style="display: none">
<h1>Items in Progress</h1>
<table data-bind="foreach: items">
<tr>
<td>
<input type="checkbox" data-bind="checked: finished" />
<span data-bind="text: title, css: { finished: finished }"></span>
</td>
<td><input type="button" value="Delete" data-bind="click: remove" /></td>
</tr>
</table>
</section>
</body>
<script type="text/javascript" src="js/jquery-1.7.2.js"></script>
<script type="text/javascript" src="js/knockout-2.1.0.js"></script>
<script type="text/javascript" src="js/jquery.signalR-0.5.0.js"></script>
<script type="text/javascript" src="signalr/hubs"></script>
<script type="text/javascript" src="js/todo.js"></script>
</html>

With a minimal amount of HTML and declarative markup for the data binding it’s very easy to integrate the data from the application with the view that the user is interacting with.

And so, using these three technologies modern, real time web applications can be built with a minimal amount of effort.

An Introduction

Well, here it is. My blog is live and ready for readers.

You may or may not know that I’m a Software Architect and Technologist by trade. Often in the course of what I’m working on I come across great ideas, tools, or solutions and have thought “I should share this so that it helps others.” Whether it’s solving small or large problems for clients, leading organizations in an implementation of a technology, or working with a start up to get off of the ground, this happens quite a lot.

So I’ve been considering starting a blog for a while, for just this purpose. I’m hoping in the weeks, months, and years to come that this blog helps others get past some the same tough problems I’ve had to solve myself. Or at least is a jumping off point to that solution.