HOWTO: Dial up the static on Simple.Data

Yo dawg, I heard you like IntelliSense, so I put an interface in your dynamic…

One of the big problems people tend to have with Simple.Data is that it’s dynamic, which means you don’t get IntelliSense when you’re working with it. It’s common for people to wrap Simple.Data in a repository which has almost the exact same signatures as the Simple.Data calls, like this:

public class CustomerRepository : ICustomerRepository
{
    private readonly dynamic _db = Database.Open();
    public Customer Get(int id)
    {
        return _db.Customers.Get(id);
    }
}

Then a team can use the repository class with all the IntelliSense and sanity checking that goes along with that. I’ve used this pattern myself. One day I started wondering if there might be a way to automatically generate proxy classes around Simple.Data’s dynamic objects to implement the interfaces, and during the course of my investigations, I found a project called Impromptu-Interface.

Impromptu-Interface

This project exists to address the lack of structural typing in C#. Remember in the TypeScript post, I mentioned how that language includes structural typing, so if an object has all the required members of an interface it is considered to implement that interface implicitly. C# doesn’t do that, but with Impromptu-Interface, you can explicitly say that object O implements interface I by wrapping a proxy around it. And you can do this with dynamic objects as well as statically-typed ones.

When I first discovered this project about a year ago, it wouldn’t recursively apply interfaces, but there was a feature request in for that and I recently checked again and it’s done, so I had a go at using it to apply interfaces to Simple.Data objects. It works really well. Take these interfaces, for example:

Lots of interfaces there. The IDatabase interface is to be applied to the dynamic database object, and includes properties for the Customers and Employees tables. Each of those has its own interface, with declarations for methods that are implemented by Simple.Data’s runtime jiggery-pokery. Note the UseNamedArgument attribute on the Insert methods; that’s an Impromptu attribute that tells it to include the argument names when it invokes the dynamic method.

I’ve also created interfaces for the Customer and Employee data objects; these interfaces will be applied to the SimpleRecord objects that are returned from queries, inserts, and so on.

Using Impromptu-Interface to apply these interfaces is embarrassingly easy:

It’s just that one call to ActsLike, and you’re done.

To illustrate how this works, here are some tests:

Neat stuff

Lazy-loading

I think my favourite thing is that lazy-loading still works with the IList<IEmployee> Employees property on ICustomer, and the ICustomer Employer property on IEmployee. When Simple.Data materializes statically-typed instances of DTOs or entity classes, you lose any lazy-loading that you would have got from the SimpleRecord object.

Inversion of Control

The other nice thing that this facilitates is dependency injection. You can take a dependency on ICustomers in your code, and configure your IoC container to return an Impromptu proxy. When you add a new method to the ICustomers interface, as long as it matches a Simple.Data method, it’s just there, you don’t need to change any other code.

No additional dependencies

A lot of projects that do stuff like this have a bunch of external dependencies on things like Castle Windsor. Impromptu-Interface is a single assembly and the NuGet package has no dependencies, so you can drop it into your project without worrying about bloat or conflicts or any ot that stuff.

Limitations

So this is still not going to run any kind of compile-time check over the interfaces to make sure that you’ve got the method and property signatures right, but it will catch any errors people make consuming those interfaces, and it gives you a nice neat bundle of things you can write some tests against.

Think of this as a way of defining a canonical set of Simple.Data method calls that can be used in your project, with all the tooling help you expect from your IDE.

ImpromptuInterface is available on NuGet. Make sure to update to the latest Simple.Data (0.18.2.1 at time of writing), because I had to tweak a couple of things to optimize the experience.

Comments

  1. I think this is great! But … I didn’t really grok it when I read your post.

    So I created a little project from your files and tried it out. And when you “feel” the intellisense and saw the lazy loading stuff in the project it all made even more sense.

    Even wrote a test (and removed it later) a test called should_make_me_get_what_mark_meant.

    You, and others can find my code in a little zip-file here: http://bit.ly/XXFOg0

    Thanks for a great post and an even greater framework!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 3,750 other followers

%d bloggers like this: