Comment Away

I’ve finally bitten the bullet and added Disqus support to the site. I guess my idea of wanting to control 100% of my site’s content is a dream anyway.

So go crazy with comments!

Cop this - a starter for EF6 and MVC5

Just take me to the code

As many of you know, I’ve recently started at SSW, and of course that means I get to go File->New project much more frequently than when I was 100% product development.

I have a few rules when it comes to project layout which should be par for the course

  • All domain logic is in its own project
  • All database logic is in its own project
  • All UI logic is in its own project

Unfortunately, people doing the scaffolding for MVC and EF6 seem to have a different set of priorities

  • All views should be modelled straight off an entity
  • All entities should contain all the validation required for the UI

Of course, this works fine for CRUD cases, but the moment you need some business logic, you’re in the deep end with no handrail.

Now, this is a project where the business logic is not so crazy that it warrants going full DDD - but it still deserves to have the domain easily tested and separated from the view, for maintainability.

I went for a design that gave View Models, Command Handlers, Repositories and Entities, but was limited to Transactional Consistency. It also allowed fast read-models and flexible Unit of Work usage. I thought I’d share the layout here. It is in EF6 code-first on ASP.NET MVC5, and is available on GitHub

1. Domain

The sample domain is an application for police to record speeding tickets. They enter in the license plate, the speed limit and the vehicles speed. They may optionally enter the vehicle’s make and model.

If a vehicle in the system already has the license plate, then the ticket is linked to the corresponding vehicle. Otherwise, a new vehicle is created and will eventually be synced with an external system.

Further, if the vehicle was not in the system, and the make and model was provided, it is used as the initial values for the vehicle. Otherwise, it is ignored.

At a later date, the officer may mark the speed ticket as paid.

Entities

There are two entities here - a speed ticket and a vehicle.

These will exist as POCOs in the domain project.

public class Ticket
{
    public int Id { get; set; }
    public Vehicle Vehicle { get; set; }
    public int SpeedLimit { get; set; }
    public int ActualSpeed { get; set; }
    public bool IsPaid { get; set; }
}

public class Vehicle
{
    public int Id { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

Commands

All commands are in the domain project, and are simply serialized method calls.

public class IssueTicketCommand
{
    public string LicensePlate { get; set; }
    public int SpeedLimit { get; set; }
    public int ActualSpeed { get; set; } 
    public string Make { get; set; }
    public string Model { get; set; }
}

public class PayTicketCommand
{
    public int TicketId { get; set; }
}

Command Handlers

Note this is not CQS. DB-generated ids are prevelant, and I thought it an ok tradeoff for the nicer URL that it offers over using guids. So commands that create entities will return the entity that was created.

This also lives in the domain project.

public Ticket Handle(IssueTicketCommand command) 
{
    if (command.ActualSpeed <= command.SpeedLimit)
      throw new SpeedLimitNotExceededException();
      
    var vehicle = _vehicleRepository.Find(command.LicensePlate)
      ?? CreateVehicle(command.LicensePlate, command.Make, command.Model);
      
    var ticket = new Ticket
    {
        Vehicle = vehicle,
        SpeedLimit = command.SpeedLimit,
        ActualSpeed = command.ActualSpeed
    };
    _ticketRepository.Create(ticket);
    return ticket;
}

private Vehicle CreateVehicle(string licensePlate, string make, string model) 
{
    var vehicle = new Vehicle
    {
        LicensePlate = licensePlate,
        Make = make,
        Model = model
    };
    
    _vehicleRepository.Create(vehicle);
    
    return vehicle;
}

public void Handle(PayTicketCommand command)
{
    var ticket = _ticketRepository.Get(command.TicketId);
    
    if (ticket == null)
      throw new TicketDoesNotExistException();
    
    if (ticket.IsPaid)
      throw new TicketIsAlreadyPaidException();
        
    ticket.IsPaid = true;
    _ticketRepository.Save(ticket);
}

These methods are trivially testable, and do not make any assumptions about persistence - in fact, they’re quite close to the usual DDD repository pattern, with a repository per aggregate root.

However, I’ve been loose with transactions here - there are none in the command handlers, so it’s up to the application to set up the TransactionScope or UnitOfWork or whatever is cool.

The sample application will use a per-request UnitOfWork that’s committed in the controller.

Of course, in a perfect DDD world, the vehicle would likely be eventually consistent, and not related via a primary key, but I feel that’s complicating this simple project.

2. Data Access

I have purposely not extracted a generic EntityFrameworkRepository as base classes for these, for brevity.

public interface IUnitOfWork
{
    void Commit();
}

public class CopContext : DbContext, IUnitOfWork
{
    public CopContext() : base("CopContext") 
    {
        Configuration.LazyLoadingEnabled = false;
        Configuration.AutoDetectChangesEnabled = false;
    }
    
    public DbSet<Ticket> Tickets { get; set; }
    public DbSet<Vehicle> Vehicles { get; set; }
    
    public void Commit() {
        SaveChanges();
    }
}

public class EntityFrameworkTicketRepository : ITicketRepository
{
    private readonly CopContext _context;
    
    public EntityFrameworkTicketRepository(CopContext context) {
        _context = context;
    }
    
    public Ticket Get(int id) 
    {
        return _context.Tickets.AsNoTracking().FirstOrDefault(t => t.Id == id);
    }
    
    public void Create(Ticket ticket) 
    {
        _context.Tickets.Add(ticket);
    }
    
    public void Save(Ticket ticket) {
        _context.Tickets.Attach(ticket);
        _context.Entry(ticket).State = EntityState.Modified;
    }
}

public class EntityFrameworkVehicleRepository : IVehicleRepository
{
    // ... etc.
    public Vehicle Find(string licensePlate) 
    {
        return _context.Vehicles.AsNoTracking().FirstOrDefault(
            v => v.LicensePlate == licensePlate
        );
    }
    // ... etc.
}

The design here is that the repositories don’t do persistence themselves, but rely on the contexts to be the same instance, and be commited externally via the unit of work implementation.

To be honest, the unit of work implementation here is pretty close to pure laziness, but it works well enough for our use case.

Important: Search methods in this pattern should never return tracked entities Save methods need to ensure that they mark the model as modified after attaching, or it will never be saved.

3. UI

The views are trivial given the right models, so here’s the controller

// View Model example
public class TicketRow
{
    public int Id { get; set; }
    public int SpeedExceededBy { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    
    public static readonly Expression<Func<Ticket, TicketRow>> Projection = ticket => new TicketRow {
        Id = ticket.Id,
        SpeedExceededBy = ticket.ActualSpeed - ticket.SpeedLimit,
        LicensePlate = ticket.Vehicle.LicensePlate,
        Make = ticket.Vehicle.Make,
        Model = ticket.Vehicle.Model
    };
}

public class TicketsController
{
    public TicketsController(TicketCommandHandler ticketCommandHandler, IUnitOfWork unitOfWork, CopContext context) {
        _ticketCommandHandler = ticketCommandHandler;
        _unitOfWork = unitOfWork;
        _context = context;
    }
    
    public ActionResult Index()
    {
        IEnumerable<TicketRow> tickets = _context.Tickets.Include("Vehicle")
            .Where(t => !t.IsPaid)
            .Select(TicketRow.Projection);

        return View(tickets);
    }

    public ActionResult Create([Bind]IssueTicketCommand issueTicket)
    {
        var ticket = _ticketCommandHandler.Handle(issueTicket);
        _unitOfWork.Commit();

        return RedirectToAction("View", new {id = ticket.Id});
    }

    public ActionResult Pay([Bind]PayTicketCommand payTicket)
    {
        _ticketCommandHandler.Handle(payTicket);
        _unitOfWork.Commit();

        return Redirect("Index");
    }
}

We’ve made a critical decoupling here that will save your views from polluting the domain - view models are simply projections from the db sets - with .AsNoTracking(). Of course, this could be abstracted again.

This is pretty powerful - the projections will be done in the database query, so you’ll only be getting what you need for the view model, not everything from every entitiy. Filtering is also trivially done from expressions - so again, in the query itself.

4. Setup injection

Autofac will be our container of choice - specifically the Autofac MVC QuickStart.

Beyond this though, let’s look at the additional setups - command handlers, repositories, and our data layers all need to be set up

public class CopModule : Module
{
    public override void Load(ContainerBuilder builder)
    {
        var domainAssembly = typeof(Ticket).Assembly;
        var dataAssembly = typeof(CopContext).Assembly;
        
        // Register command handlers
        builder.RegisterAssemblyTypes(domainAssembly)
            .Where(t => t.Name.EndsWith("CommandHandler"))
            .AsSelf().AsImplementedInterfaces();
            
        // Register repositories
        builder.RegisterAssemblyTypes(dataAssembly)
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces();
            
        // Register database stuff
        builder.RegisterType<CopContext>()
            .InstancePerRequest()
            .AsSelf().As<IUnitOfWork>();        
    }
}

Everything except the context and unit of work are transient dependencies by default, and we’ve made our per request.

5. Win!

That’s it! Run your project and be happy that you’ve isolated your domain, used entity framework and MVC, got dependency injection and everything is super squeaky clean.

Be sure to check out the sample project on GitHub!

Please if you have any suggestions for improvement - especially a more reliable (but still simple) transactional consistency, let me know on the twitters!

Making WebStorm Friendlier

There’s a few settings I recently tweaked in WebStorm that vastly improved my development experience.
Here’s a quick rundown.

Ensure “Show Reformat Code” is disabled

Show "Reformat Code" dialog

Make sure these guys are off to get the popups out of your way. I also remap the commands to Ctrl+K, D and Ctrl+R, S to match my Visual Studio setup.

Tweak code completion popups

This is the setup I use:

Code Completion

The most important one is the Parameter Info popup - I really like having the method signatures there all the time, so making this nice and small makes it much more useful. I’d recommend trying “Insert selected variant by typing dot, space, etc” as well, for more natural completions. Can be annoying, though

Key Bindings

The default key bindings are a little all over the shop. Here’s some handy ones:

  • Ctrl+T: Navigate to symbol
  • Ctrl+Shift+T: Navigate to file
  • F2 and Ctrl+R, R: Rename (works for files and symbols)
  • Alt+Enter: Autocomplete
  • Alt+Home: Super types hierarchy
  • Alt+End: Sub types hierarchy
  • Ctrl+R, S: Optimise Imports
  • Ctrl+K, D: Reformat Document

Some of these are muscle memory from my Visual Studio settings at work, but be sure to make them something you use, because they are all VERY useful commands.

Plugins

The best plugin I’ve seen is Key Promoter. This handy extension shows a popup whenever you do something inefficiently. For example, if I go to Settings via the menu, instead of Alt+F7, it’ll show a blocker for 1s that shows the shortcut in an impossible to miss way. Recently, it noticed that I use “Close all documents” a lot, and nagged me to make a shortcut for it. I can now use Ctrl+Shift+W for that purpose, and it will nag me if I don’t.

Foray into node.js on Windows 7

I’ve decided to learn about node.js - it’s about time, really. I’ve used it - but only so much as to run a grunt task to bundle a specific revision of an Angular directive.

I found this neat tutorial for picking up some node.js know-how - looks pretty decent, and I’ll give feedback on that in a subsequent post. Meanwhile, here’s a rundown of getting the basic environment up for those on Windows who are having issues (as I did)

Installing NodeJS with NPM

I must have had this idea a little while ago, because I thought my first step should be to find out what I’ve got installed so far - it turns out I have 2 versions installed from Chocolatey, and one from the official installer, all old versions. So I got rid of them all, and discovered from the helpful comments at the package page for nodejs that I should use nodejs.install instead.

c:\Development\node-learning>node -v
v0.10.28

c:\Development\node-learning>npm -v
1.4.9

Woohoo!

NPM issues

Installing express proved difficult - the mime package kept giving me permission errors and this:

npm ERR! Error: ENOENT, chmod 'C:\Users\*****\AppData\Roaming\npm\node_modules\express\node_modules\accepts\node_modules\mime\README.md'

Whatever that means.

I kept going around in circles - the prevailing wisdom seems to be to clean the npm cache or to run as administrator.

I tried these (alongside an npm uninst -g for everything to get a clean start), and it worked a treat. I then removed all the modules again, cleaned my cache, and tried again, to make sure my solution was valid.

npm ERR! EEXIST, mkdir 'C:\Users\*****\AppData\Roaming\npm\node_modules\express\node_modules\send\node_modules\mime'
File exists: C:\Users\*****\AppData\Roaming\npm\node_modules\express\node_modules\send\node_modules\mime
Move it away, and try again.

It wasn’t. I’ve made sure %appdata%/npm-cache is empty as well, to no avail. I sometimes get a few other errors, which seem to cycle around - even though the cache and modules are empty

npm ERR! Error: ENOENT, chmod 'C:\Users\*****\AppData\Roaming\npm\node_modules\express\node_modules\type-is\node_modules\mime\LICENSE'

npm ERR! Error: ENOENT, lstat 'C:\Users\*****\AppData\Roaming\npm\node_modules\express\node_modules\send\node_modules\mime\types\mime.types'

I’m sure I got an EPERM here as well.

I’ve since learned that ENOENT means “No such file or directory”. I’m well into yak-shaving territory at this point.

The light!

In the end, I just kept running npm install express -g until it worked. It’s intermittent, which makes me think this stuff installs in parallel or there’s a load balancer serving the wrong file or something. Not much of a light, but them’s the breaks.

Running npm install for the package had similar issues. As before the “keep on trying” Method works, and works in fewer iterations if you install it package-at-a-time. I couldn’t find any documentation about parallel installs, so I’ve no idea what’s going on.

Be sure to let me know if you know what’s going on here!

In any case, it was easy sailing from here on out. The tutorial was straight forward, though it reminded me of my PHP days (jam the DB object into the request object? Really?)

Undirect updated to 1.1.1, and some "gotchas"

I’ve updated Undirect, a Chrome plugin that prevents annoying redirects on the google search page, because it had stopped working. I ran into a few surprises along the way, and some old frustrations cropped up again, here’s a rundown to help the next person who tries.

Chrome store feedback

Since I’d released this in 2011, with a small update in 2012 to add RegEx to the pattern, I’d basically stopped checking the store’s feedback. I couldn’t find a way to get notifications of comments (apparently I’m not the only one) - and checking every few months is something that I probably could have done, but it never crossed my mind.

Now I wish I had, because apparently the plugin hasn’t been working since about August 2013 - and I hadn’t even noticed. Which is especially concerning, because I use the plugin on all my machines, and so do a lot of friends of mine. Being able to get notifications of reviews would have served me well here, since the average Joe won’t exactly raise an issue on GitHub

Manifest JSON

The manifest.json file has been updated to v2, and v1 can no longer be updated on the Web Store. Not a big deal, but there were a few new things about the configuration file which were non-obvious.

  • default_locale is noted as “recommended” field, but without also having a _locales directory with the localisation, you get a confusing error when trying to load it.
  • The documentation page for it looks good for a sample, but it took me a while to realise that the field names are clickable. If you’re looking for documentation, click those links!
  • The sample uses comments to mark off sections - but keep in mind this isn’t valid JSON! You’ll need to take them out before uploading to the store

Isolated world - why it broke

The reason for the extension breaking was a “security” feature they’ve added to the extension. I put security in quotes, because it’s easy to circumvent.

Content scripts now run in an isolated world - which means that while it has access to the page and the DOM and all the jazz, it’s a different view than the page. Any scripts or variables that are added by the page are inaccessible from the script - in my case, the onmousedown attribute of the link tags didn’t exist from the content script’s perspective.

I thought all hope was lost, then came across a neat little workaround, which is basically to add a <script> tag to the head element, causing it to execute in page context. Circumvented!

In my case, I wrote the function I wanted to execute as usually, then added the script to the page by simple calling .toString() on the function. Simple, and I get the full power of my IDE while I’m at it! Here’s an example

var fnToRunOnPage = function() {
  // code goes here
};

var fnContents = '(' + fnToRunOnPage.toString() + ')();';

var scriptTag = document.createElement('script');
scriptTag.textContent = executeFnScript;
(document.head || document.documentElement).appendChild(scriptTag);
scriptTag.parentNode.removeChild(scriptTag);

It’s the same thing that jQuery does when you add an element with a script tag in it. Works a treat!

The new solution

Previously, my plugin would search all the anchor tags, look for ones that had an onmousedown script with return rwt in it, and remove the value. Every time a DOM element was added or removed, I would run it again.

That’s updated now to simply overwrite the rwt function on window to one that does nothing. I (perhaps unnecessarily) future-proofed it against overwrites by making it a property with writeable: false as well. Futile, probably - I’m sure they could get around that simple enough, but I have nothing to lose by doing that.