Typescript interfaces for C# developers

Or, how not to make the mistakes I made with Typescript.

As a long-time .NET developer, I took the plunge into TypeScript a couple of years ago after much uhm-ing and ah-ing. I learned that you could write interfaces in TypeScript, and I immediately starting doing them wrong.

In .NET, an interface is something that you expect to be implemented in a class. For example:

public interface IFoo {
    string Bar { get; }
    string Baz(string bar);
}

public class FunkyFoo {
    public string Bar { get; set; }
    public void Baz(string bar) => $"Hello {bar}";
}

You might code against the interface, but you would only really create interfaces if you expected several different concrete classes to implement that contract.

When I started writing TypeScript, I wrote interfaces in much the same fashion:

interface IFoo {
    string Bar;
    Baz(bar: string);
}

class FunkyFoo {
    public Bar: string;
    public Baz(bar: string): string {
        return `Hello ${bar}`;
    }
}

The problem is that, while this works, it’s not really giving you the full benefit of TS interfaces. TypeScript, being a super-set of JavaScript, is a functional language – unlike .NET, the classes aren’t the most important thing in it. Using the approach above, I was writing code like:

let foo: Array<IFoo>;
$.getJSON("foo/bar", json => {
    for (let i = 0; i < json.length; i++) {
        foo.push(new FunkyFoo(json[i]));
    }
}

Ugh. Horrible and messy. If I’d used interfaces properly, I’d have something like this:

interface Foo {
  bar: string;
  baz: string;
}

// ...

let foo: Array<Foo>;
$.getJSON("foo/bar", json => {
    foo = json;
});

The realisation that dawned on me was that interfaces are just data contracts – nothing more. Due to the loose typing of JavaScript, I could quite happily say that an object was of type Foo, without doing any conversion.

So, what should I have been using interfaces for? Well, firstly, data contracts as seen above – basically just a way to define what data I expect to get from/send to the server. Secondly, for grouping sets of repeated parameters, as in:

function postComment(email: string, firstName: string, lastName: string, comment: string) {
  // etc
}

// becomes:
interface UserInfo {
    email: string;
    firstName: string;
    lastName: string;
}

// now the method is much cleaner,
// and we can re-use these parameters
function postComment(user: UserInfo, comment: string) {
  // etc
}

I’ve ended up thinking of interfaces as more akin to records in F# – just basic DTOs. Doing this has actually made my code better – now I have a clean separation between data and functionality, rather than mixing both in the same structure.

De-coupling after the fact

This post was prompted by Facebook’s recent decision, at the time of writing, to withdraw their Parse app platform. This is a prime example of why you should make all reasonable efforts to de-couple your application/business logic from your platform logic: it’s much more difficult to migrate a tightly-coupled application than a loosely-coupled one.

That said, I also came to the realisation that a well-written, DRY application should be relatively easy  to de-couple retrospectively. How? Let’s take some examples.

The code

Let’s take as our example a module that saves user files to disk against an entity in a SQL database (for example, storing blog post assets). Firstly, let’s take a naive, highly-coupled approach:

private const string RootPath = "\\\\server\\share";

public void SaveFile(int entityId, string fileName, Stream fileStream)
{
    // should produce: \\server\share\1234\file.txt
    var fullPath = Path.Combine(RootPath, entityId, fileName);
    if (File.Exists(fileName))
    {
        throw new Exception("File already exists!!");
    }
    using (var fs = FileStream.Create(fullPath))
    {
        fileStream.CopyTo(fs);
    }
}

public IEnumerable LoadFiles(int entityId)
{
    var fullPath = Path.Combine(RootPath, entityId);
    return Directory.GetFiles(fullPath);
}

public Stream LoadFile(int entityId, string fileName)
{
    var fullPath = Path.Combine(RootPath, entityId, fileName);
    if (File.Exists(fullPath))
    {
        return File.OpenRead(fullPath);
    }

    throw new FileNotFoundException("Can't find the file", fullPath);
}

Actually, this isn’t particularly highly-coupled. What we have is a module that deals with loading and saving files. In our application code, we might have methods like:

public ActionResult Download(int entityId, string fileName)
{
    try {
        var mgr = new FileManager();
        var data = mgr.LoadFile(entityId, fileName);
        return new FileStreamResult(data, "application/octet-stream");
    } catch (Exception ex) {
        return new HttpStatusCodeResult(500);
    }
}

In this method, we instantiate a new instance of our dependency, and then use that dependency to perform our application logic. If all of our application is written like the code above, we don’t really have much of a problem. Why? Think about it: all we actually have to do to turn this into a fully de-coupled application is:

  • Create an interface from our FileManager object
  • Create a new implementation using our new underlying platform (for example, using Amazon S3 storage, or WebDAV)
  • Replace all instances of our old class with the new one (if need be, changing any references from FileManager to IFileManager)

That’s just typing. It’s a night of find/replace and manually fixing the edge cases, but it’s not a nightmare – all of your platform logic is already encapsulated into an object, and that object can be replaced.

Where it all goes wrong

So what’s the problem? That happens when code doesn’t keep itself DRY. In the example above, the developers kept all of the logic around saving and loading files in a single object, and then used that object as a gateway for all file functions. By doing this, they made it very easy to change the behaviour of IO (there are many other benefits, such as making it easy to add logging and error handling).

In a depressingly large number of applications, this does not happen. What happens is that the developers know the common location for saving files, and so they either don’t write a centralised component, or, if they do, they don’t always use it. Instead, you see code like this:

public ActionResult Download(int entityId, string fileName)
{
    try {
        var path = $"\\\\server\\share\\{entityId}\\{fileName}";
        var data = File.OpenRead(path);
        return new FileStreamResult(data, "application/octet-stream");
    } catch (Exception ex) {
        return new HttpStatusCodeResult(500);
    }
}

The problem is that the above code is often repeated throughout the application – the developers found it easier to write the logic every time than to write, or use, a re-usable component.

When you have code like that above, de-coupling becomes more difficult, and can become totally impractical (especially if the logic is replicated across multiple applications in various languages – yes, this really does happen: I’ve supported an app where such logic was repeated across VB6 components, C# services, a classic ASP application and JavaScript).

Conclusion

If your code is DRY, then events like the Parse shutdown should be annoying rather than catastrophic. To quantify it:

  • Code is de-coupled and uses DI for dependencies
    = Write new dependencies, config change – late night and pizza
  • Code is DRY but doesn’t use DI
    = Write new dependencies, create interfaces, find/replace – long weekend or a few late nights
  • Logic is repeated through the app
    = Find new job

The disaster of OOP, and what we can salvage

Object Oriented Programming is a disaster, or at least that’s what Brian Will thinks, and I’m not about to disagree. I share his disillusionment with OOP, and I have always had a sneaking admiration for the PHP and JavaScript developers who just seem to get stuff done much faster than their static-typed object brethren.

However, one paragraph did stick out:

In [the] original vision, an object-oriented program is composed of a graph of objects, each an island of state unto itself. Other objects do not read or write the state of other objects directly but instead send messages.

Just because OOP as we write it today hasn’t produced the benefits we sought, doesn’t mean that there is no value in the original concepts. The difference between now and then is one of scale: how many of you out there are actually writing single programs, where a system is composed of objects that all live in a single app domain and communicate via messages?

I don’t think I’ve ever written such an app (it’s much harder in the web world in any case, where the app simply has no state from one request to the next). Where I have been writing actual, run-in-memory-UI-and-everything applications, they’ve been small utility apps that I’ve thrown together using RAD, that simply wrapped functionality that already existed in databases or services.

That, right there, is the part where OOP hasn’t failed – it has just, like the Roman Empire, transformed into something else. Instead of objects, think services – think how an enterprise system is composed of many disparate systems, services and databases, each of which are tied together by some form of message. In the worst case, they share state promiscuously and become an un-maintainable tangle, but in the best cases, we have services that sit serenely in the heavens and send messages back and forth to each other.

Or we could just hack it together with PHP and buy a bigger server.

Devops is just what you do in an SME

On reflection, I think I was fortunate to begin my career in a small organisation (80 employees with 2 IT techs and 4 developers at our biggest). I began my career converting Word documents into HTML in Dreamweaver to burn onto CDs for our clients. Then, I started building sites in Classic ASP and SQL Server, then I had to take on the role of SysAdmin. A year or so after that, we took on our first developer, and we became an ISV. A few months later, we had dedicated IT techs.

We never even knew there could be a split between dev and ops. We were developing the software, and we ran the servers. We scripted deployments (not entirely, but in large part), we wrote monitoring scripts, we set up production environments, we wrote scripts to replicate the production environment on our workstations.

We never reached the ideal of continuous, automated deployment but, on the other hand, we could (and did) make changes to internal and external systems with a few hours’ notice. The developers often spoke directly to clients and end-users, and we were often in a position to prototype change requests whilst the client was still in the meeting.

Moving from that environment to ones with a more traditional split between development and operations was an eye-opener, to say the least. Battling change control, ticket management and miscommunications taught me a whole raft of skills that I never even thought I’d need.

So if you want to hire people with a devops state of mind, recruit from SMEs – you might be pleasantly surprised.

Merging ModelState validation with Knockout models

Scenario: you have a server-side object in .NET, which you then serialize across to a client-side Knockout view model. Knockout supplies validation on the client-side, but you have one or two rules that you want to enforce on the server and only on the server, and for whatever reason you don’t want to run these asynchronously.

So let’s assume that you’ve got something like this:

public class LoginModel
{
    public string Username { get; set; }
    public string Password { get; set; }
}

This maps to a Knockout model which looks a little like:

function loginModel() {
  this.Username = ko.observable('').extend({ required: true });
  this.Password = ko.observable('').extend({ required: true });
}

All good. Let’s say that your controller action does this:

public IActionResult Login(LoginModel model)
{
  if (!CheckPassword(model.Username, Model.Password))
    ModelState.AddModelError("Password", "Invalid password");

  if (ModelState.IsValid)
  {
    // continue
  }

  return HttpBadRequest(ModelState);
}

Now, in your UI code, you can use the following snippet the map the server-side validation errors into your client-side model:

/**
 * Applies errors returned via the .NET model state error collection to a Knockout
 * view model by matching property names.
 * @param koModel Knockout view model to bind to
 * @param modelState Model state response (usually returned as JSON from an API call)
 */
function applyModelStateErrors(koModel, modelState) {
    // loop all properties of the `modelState` object
    for (var x in modelState) {
        if (modelState.hasOwnProperty(x)) {
            // try to get a property of our KO object with the same name
            var koProperty = koModel[x];

            // we're only interested in KO observable properties
            if (koProperty &amp;&amp; ko.isObservable(koProperty)) {
                var error = modelState[x];
                var message = "";

                // .NET returns errors as an array per-property, but we
                // can check the type just to be safe
                if (error instanceof Array) {
                    message = error.join(", ");
                } else if (typeof error == "string") {
                    message = error;
                } else {
                   message = error.toString();
                }

                // set the error state for this property
                koProperty.setError(message);
            }
        }
    }
}

Given this, you can catch the 400 error in your AJAX call, use the function above, and map the server-side errors into your local model.

Entity Framework dynamic sorting

I have a fairly common requirement to enable user-defined sorting, for example using a querystring like so:

?page=2&sort=name&desc=true

This isn’t really catered for using LINQ, due to type-safety (you need to use an expression based on a property of your object to do sorting). To enable dynamic sorting on an IQueryable object, try this:

private static readonly MethodInfo OrderByMethod =
    typeof(Queryable).GetMethods()
    .Where(method =&gt; method.Name == "OrderBy")
    .Where(method =&gt; method.GetParameters().Length == 2)
    .Single();

private static readonly MethodInfo OrderByDescendingMethod =
    typeof(Queryable).GetMethods()
    .Where(method =&gt; method.Name == "OrderByDescending")
    .Where(method =&gt; method.GetParameters().Length == 2)
    .Single();

public static IQueryable DynamicOrderBy(this IQueryable source, string sortBy, bool sortDescending = false)
{
    if (string.IsNullOrWhiteSpace(sortBy))
        return source;

    if (sortBy.Contains(','))
    {
        foreach (var sort in sortBy.Split(','))
        {
            source = source.DynamicOrderBy(sort, sortDescending);
        }

        return source;
    }
    else
    {
        var type = typeof(TSource);
        var parameter = Expression.Parameter(type, sortBy);
        var propertyRef = Expression.Property(parameter, sortBy);
        var lambda = Expression.Lambda(propertyRef, new[] { parameter });

        MethodInfo genericMethod = (sortDescending ? OrderByDescendingMethod : OrderByMethod)
            .MakeGenericMethod(new[] { typeof(TSource), propertyRef.Type });
        object ret = genericMethod.Invoke(null, new object[] { source, lambda });

        return (IQueryable)ret;
    }
}

Putting this in your code allows you to write something like this:

IQueryable data = GetData();
var sortedByNameDescending = data.DynamicOrderBy("Name", true);

Fun with T-SQL Computed Columns

First, please take a minute to check out the first video from my old friend Chris Saxon:

This reminded me of a trick I’ve used in a couple of SQL Server databases using a similar technique.

When storing details of people, you often find that the first and last names have their own columns; this makes sorting easier, but if you’re trying to retrieve the whole name as a single column, then it’s a pain to always remember to write FirstName + ' ' + LastName. Initially, I made my life easier by adding this:

CREATE TABLE Person (
Id INT IDENTITY NOT NULL PRIMARY KEY,
FirstName NVARCHAR(100) NOT NULL,
LastName NVARCHAR(100) NOT NULL,
FullName AS FirstName + ' ' + LastName PERSISTED
)

Better – we can now query on our computed FullName column and, because we’ve used the PERSISTED flag, there’s little to no overhead in doing so (the value is stored physically rather than being computed on the fly). However, in a moment of whimsy, I took it a step further:

ALTER TABLE Person ADD NameFormat TINYINT NOT NULL DEFAULT (0)

ALTER TABLE Person ALTER COLUMN FullName AS
  CASE (NameFormat)
    WHEN 1 THEN (LastName + N', ' + FirstName)
    WHEN 2 THEN (SUBSTRING(FirstName, 1, 1) + N'. ' + LastName)
    WHEN 3 THEN (LastName + N', ' + SUBSTRING(FirstName, 1, 1) + N'.')
    ELSE (FirstName + N' ' + LastName)
  END PERSISTED

Depending on the value of the NameFormat field, my name renders as either “Keith Williams”, “Williams, Keith”, “K. Williams”, or “Williams, K.”.

If name formatting was a big deal, then I’d recommend you do it in the application layer rather than SQL (and especially if you’re handling non-European names), but the approach above gives you a convenient way of storing basic formatted names without repeating code or calling scalar functions.

Your team should make mistakes – and take the consequences

Much and more has been written about how technical managers should not impose control on their teams, but instead act as facilitator and coach to the team, whilst the team makes its own decisions, some of which will, inevitably, be wrong.

Having worked at organisations where “autonomy” meant “any way you like, so long as it’s the way I would have done it”, which, given that this ethos came down from the highest echelons, effectively rendered all senior and middle managers irrelevant since all they could do was relay orders, I can wholeheartedly endorse this theory. The more knowledge, control and motivation you have at the lower levels of your people stack, the better the machine will work in aggregate. Put simply, if you made the decision, you are more likely to care about it; the more you care about a decision, the more work you will put in, and the better your quality of decision making.

However, the one thing that is often left out of these writings is the Dark Side of this equation:

Freedom to make decisions is beneficial so long as those making the decisions are exposed to the consequences

Take a lumbering corporate command-and-control behemoth, and try giving the team freedom to make decisions. Said team has been used to mushroom management for so long that they don’t even know who the clients are, let alone what the point of their product actually is. Given them decisions to make, and they’ll make decisions that make their life easier, because that’s the only set of requirements that they understand. When the project crashes and burns, it’ll be the layer above them that takes the consequences. This may filter down to the team, but more likely their boss will be sacked, and the team will go back to being ignored.

Now, take this team, and put them in actual control – make them talk to the clients, have them make the promises, put them on the phones when things go wrong. A developer who implements an ill-thought-out spec from a bit of paper can understandably make a half-arsed job of it, but if said developer is on speaking terms with the client who requested said feature, and knows that the feature will make this client’s life that much easier, then empathy kicks in, and the developer starts to care about their work.

Managers should shield technical teams from the minutiae of detail that will just get in their way otherwise, but if the team is granted the freedom to decide their own destiny, then the team should also know and understand that the freedom to succeed is also the freedom to fail.

How they cope with that failure is perhaps the most important decision that they can make.

Why Red-to-Green projects just add more Red

A Red-to-Green project is one that aims to take an old, shoddy system (“red”) and, bit by bit, turn it “green” – in practice, by replacing each old component in turn by a newer piece of code.

The logic behind this is that the system stays operational whilst developers add newer modules and services, with appropriate shims and interfaces so that the remaining legacy code thinks it’s still talking to its old buddies.

An example: you have an ancient web application which consists of a SQL database, a set of COM+ objects in VB6, and a Classic ASP front-end. Using RTG methodology, you could write a new version of each COM+ object using, say, C#, which exposed the same COM-visible methods as the old object. You could install the new object in COM+, and the website should, in theory, continue to work as normal – at the same time, you could code newer parts of the website in ASP.NET MVC and use the DLL directly (or maybe within a service). Alternatively, you could go ahead and rewrite some particularly grotty ASP pages in MVC, and create an interop library which talks to the COM+ objects but exposes a more pleasant API for ASP.NET to use.

Neat. What’s the problem?

It’s too good to be true.

Red-to-Green, like many bad ideas, sounds fantastic to management:

What’s that Jenkins? You say you can rebuild our software whilst still keeping the application running and delivering new features? You say that this new ‘green’ stuff will make development faster? By Jove, when can you start?!

This is bullshit. This is what actually happens:

  • Developers begin coding new modules in <modern language of choice>. Usually, the choice of modules will revolve around business needs – i.e. Customer X wants feature Y, so can we use this Red-to-Green stuff to deliver Y faster?
  • An amount of time is taken up with the basic plumbing – creating base classes, defining an interop layer (.NET to COM+, Ruby to PHP, views over an old SQL schema etc.) – but things will really start to move once this is done!
  • The developers start implementing feature Y. Instantly, their new architecture comes into conflict with the old – no-one told them (or remembered) that this batch VBA script needs to run in the background to copy files, or that the format of filenames is actually really important for this module
  • The new, green components now consist mostly of code which replicates, or compensates for, the eccentricities of the legacy code base. If not, the new code is now wholly reliant on calling methods in the old codebase, and is now tightly coupled with the legacy code.
  • Feature Y is delivered – probably late, but that’s OK, because the RTG pattern is established now, right?
  • Feature Z, which involves modifying a small part of the legacy system, needs to get information from Feature Y. The developers write an interface so the legacy codebase can talk to the new one. The green components are now coupled to the red, and vice versa.
  • Management begins to lose interest – there are paying customers out there, and Red-to-Green is taking too long and causing too much confusion. Who cares that the email formatting engine is a tangled mess of VB6? It works, so leave it alone! We’ll allocate some more time in the new year.

At this point, the green components are now just a different flavour of legacy code: they go to join the swamp of rotting code, more meatballs in the Great Spaghetti Monster.

When to Inject a Dependency

Let’s take a simple scenario: say that you’re developing a holiday request system (because the previous MS Access-cum-Excel-cum-Word jalopy that the boss wrote ten years ago has finally corrupted beyond the point of no return). You’re given the basic parameters, and then, if you’re like me, you start pseudo-coding:

class HolidayManager
{
  void RequestHoliday(Employee emp, DateTime start, DateTime end)
  {
    // TODO: sensible error messages and basic validation stuff
    if (start < DateTime.Now) throw new ArgumentOutOfRangeException();
    if (end < start) throw new ArgumentOutOfRangeException();

    // does the user have any holiday available?
    if (database.GetHolidaysRemaining(emp) == 0)
      throw new OutOfHolidayException("TODO: should we use a return code?");

    // assume that this call returns us a unique ID for this holiday
    var holidayId = database.AddHoliday(emp, start, end, HolidayStatus.Requested);

    // tell the user
    emailer.SendConfirmation(emp, start, end);

    // tell their line manager
    var manager = database.GetLineManager(emp);
    if (manager != null) // they might be the Big Boss
      emailer.SendRequestForApprovalEmail(emp, start, finish, holidayId);
    else
      this.ApproveHoliday(holidayId, HolidayStatus.Approved);
  }

  void ApproveHoliday(int id, HolidayStatus status)
  {
    // assume this struct has info about the holiday
    var holiday = database.GetHoliday(id);
    if (holiday.Status == HolidayStatus.Requested)
    {
        database.SetApproval(id, status);
        int daysLeft = database.CalculateRemainingDays(holiday.Employee);

        // send email to the requester (assume that holiday includes an email address)
        emailer.SendApprovalEmail(holiday, status, daysLeft);
    }
    else
      throw new InvalidOperationException("already approved");
  }
}

What we have here is a basic sketch of our business logic – we don’t care about how the database works, and we don’t care how emails go out, because that’s not important to us at this stage.

If, whilst pseudo-coding, you find yourself writing GetStuffFromDatabase or somesortofqueue.Push(msg), then congratulations – you’ve identified your dependencies!

Whenever you find yourself writing a quick note to cover up what you know will be a complicated process (retrieving data from a store, passing messages to a queue, interacting with a third party service, etc.), then this is an excellent candidate for a dependency.

Looking at our example, we’ve got two dependencies already:

  • database
  • emailer

Now, my point here is not to design the best holiday application imaginable – the code above is just a sketch. My point is that we’ve now identified some application boundaries, namely the boundary between business logic and services.

Let’s take this a little further: in our emailer implementation, we might have further dependencies. Say that our emailer implementation needs to format an email (given data and a template) and then send it. We might switch the formatter at some point in the future (using RazorEngine, NVelocity or just string.Format) and we might change the delivery mechanism (because the business now has a central email queue, and we need to submit messages to that instead of using SMTP directly). In this case, the business logic of the email engine is:

class HolidayEmailer {
  IEmailFormatter formatter;
  IEmailSender sender;
  IEmailLogger logger;

  void SendEmail(someObject email)
  {
    var message = new System.Net.MailMessage();
    message.To.Add(email.To);
    message.Subject = email.Subject;
    message.Body = formatter.Format(email);

    sender.Send(message);
    logger.Log(message);
  }
}

What this means is that we have many levels of DI – from the point of view of our holiday app, it has an abstraction that it can call to send emails, and we can unit test our object against a mock. We can also test our emailer implementation, because we’ve abstracted the formatting, sending and logging, which means that we can test what happens if any of these fail, or produce weird results.