Mavnn's blog

Stuff from my brain

Extracting Information From MsBuild

Recently as part of some research into making a large (very large) solution build more efficient, I started looking into whether there's anyway of getting MsBuild to do some of the donkey work for you. This is especially important in situations where you want to know what's being used/produced with this particular set of parameters.

Obviously dealing with every possible custom build target is out of scope, but you can get a surprisingly long way by taking advantage of some of the intermediate build targets used within the MsBuild Common targets files (imported into every *proj file created by Visual Studio).

Create yourself a little file called something like Analyse.proj, and put the following in it:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="WriteStuff" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(TargetProject)"/>
  <Target Name="WriteStuff" DependsOnTargets="ResolveReferences">
    <Message Importance="high" Text="References::@(ReferencePath)"/>
    <Message Importance="high" Text="Compiles::@(BeforeCompile);@(Compile);@(AfterCompile)"/>
    <Message Importance="high" Text="Output::$(OutputPath)"/>
  </Target>
</Project>

This is a mini-MsBuild project that imports an other project - the project you want to analyse. You can "build" this project like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
PS C:\DirectoryWithProj> & 'C:\Program Files (x86)\MSBuild\12.0\Bin\SBuild' .\Analyse.proj /nologo /p:TargetProject=./Fake.Shake.fsproj
Build started 07/08/2015 15:05:27.
Project "C:\DirectoryWithProj\Analyse.proj" on node 1 (default targ ets).
WriteStuff:
  References::C:\rip\Fake.Shake\packages\FAKE.Lib\lib\net451\FakeLib.dll;C:\rip
  \Fake.Shake\packages\FSharp.Core\lib\net40\FSharp.Core.dll;C:\rip\Fake.Shake\
  packages\FsPickler\lib\net45\FsPickler.dll;C:\rip\Fake.Shake\packages\Hopac\l
  ib\net45\Hopac.Core.dll;C:\rip\Fake.Shake\packages\Hopac\lib\net45\Hopac.dll;
  C:\rip\Fake.Shake\packages\Hopac\lib\net45\Hopac.Platform.dll;C:\Program File
  s (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\mscorli
  b.dll;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFra
  mework\v4.5.1\System.Core.dll;C:\Program Files (x86)\Reference Assemblies\Mic
  rosoft\Framework\.NETFramework\v4.5.1\System.dll;C:\Program Files (x86)\Refer
  ence Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Numerics.dll;
  C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework
  \v4.5.1\System.Runtime.Serialization.dll;C:\Program Files (x86)\Reference Ass
  emblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Xml.dll
  Compiles::;Fake.Shake.Core.fs;Fake.Shake.Control.fs;Fake.Shake.DefaultRules.f
  s;Fake.Shake.fs;
  Output::bin\Debug\
Done Building Project "C:\DirectoryWithProj\Analyse.proj" (default
targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.12

And as you can see, whilst it's a bit ugly it generates a whole load of useful information for you about how this build with these properties will be built.

That's all for now!

Serialization in .net

Leaving the confines of your own process's safe little memory space is always a potentially painful moment when you're coding up an up. Whether it's receiving data from the outside world, passing a message over RabbitMQ to an other in house service, or writing an audit trail that needs to be accessible for the next 20 years, there's a bunch of considerations that need to be taken into account when you hit the joys of serialization and deserialization.

API Design Workshop

Designing an API is hard.

You want to actually apply the principle of least astonishment - but you're the person who wrote the code. You're unlikely to be astonished. So you're trying to think how someone who didn't know what you know would think - which is never an easy starting point!

Similarly, you're trying to create the pit of success for users. Which means trying to make it very hard to do the wrong thing with your API. Preferably, in strongly typed languages, this should include using the type system to make illegal states unrepresentable so that code that compiles is very likely to work.

In general, the core libraries for .net are not bad at API design, but there are a few places where this isn't true. As an exercise, we at 15below are going to take one of them, split into teams and spend an hour or so seeing what alternatives we can come up with. Feel free to follow along at home, and if you do give it a try ping me a code snippet and I'll post it up with our internal attempts in a week or so.

Ecumenical APIs

One of the big sells of shared runtime functional languages such as F#, Scala and Clojure is that you can carrying on using the surrounding library ecosystem and your existing code. The different paradigm occasionally causes a little pain, but there are plenty of blog posts about how to wrap OO interfaces in a functionally friendly way.

This is not one of those blog posts. This is about making sure that your colleagues who are consuming your shiny new code in an imperative language (generally C# in my case) don't threaten to defenestrate you.

At 15below we've recently had need in some of our services of taking a distributed lock between servers. There are many services available designed for doing this, but after some deliberation we decided that we didn't want to add a new piece of infrastructure purely for this one purpose. So Sproc.Lock was born: SQL Server based distributed locking.

In this post, I'm not going to talk about the design of the service. What I'm going to write about is how I engineered the API to be pleasent to use from both C# and F#, giving a idiomatic interface from both languages.

LambdaCon 2015

This weekend I had the honour of speaking at LambdaCon. My own talk I'll be writing some separate posts on in the future, but I also wanted to jot down some notes on the conference before the memory faded.

Testing ProvidedType.fs by Example

The Type Provider Starter Pack was designed with two purposes initially. Firstly, to be a canonical repository for the ProvidedTypes files which provide a source file based API for creating type providers. And secondly, to be a set of tutorials and examples for people wanting to dip their toes into building type providers for the first time.

To be honest, it's not been doing a complete job of either:

  • I think most people are using it as the source of ProvidedTypes.fs and .fsi now days, but it didn't provide any infrastructure or testing for progressing the library.
  • The "examples" were limited to a link to my tutorial on building type providers

Today, that's changed. And I need your help!

Testing ProvidedTypes

Once I started thinking about it, it became clear that the code needed for basic type provider examples, and the code needed to test ProvidedTypes.fs were basically identical.

So I implemented a system for compiling and testing example .fsx scripts within the Starter Pack repository.

Want to help out? As long as you have some basic git and F# knowledge, it's easy!

Good Developer CVs (Résumés)

I've been reviewing a number of CVs from developers of varying experience recently, and wanted to get a few notes out there about what to do (and not do) on your CV if you want to get noticed.

Well, by me at least. Your mileage may vary with other reviewers! But - remember that you're interviewing the company as much as they're interviewing you. Hopefully this advice will get you more interest from the kind of companies you want to work for, even if it doesn't get you through the enterprise HR screen quite as often.

I'll start with the postives, and then go onto some things it's best to avoid.

Make yourself stand out!

Looking from the outside (at least, from the job descriptions!), 15below probably looks like a Microsoft shop. That's because it is - all of our new code is written in MS supported .net languages, we use SQL Server as our primary data store, WebApi, ASP.net MVC, etc.

But! One of the things that makes us who we are is that we've deliberately hired outside the box, especially for senior developer roles. I have professional Python experience, use F# by preference and run my personal computers on Linux. Three of us use Vim (or at least VsVim). One of us used to write C++ code for nuclear reactors (the testing is strong in that one). My colleagues tweet about Erlang, code for fun in Idris and steal ideas liberally from all these places to make 15below the kind of place it is. Not all of it makes it into production code, but even there you'll find technologies like RabbitMQ that don't show up that often in the Microsoft world.

If you tailor your CV to what it looks like we prefer, you immediately sink to almost invisibility. "Oh, an other developer with 5+ years C# experience who knows T-SQL and knows to buzzword Scrum onto the CV." To be clear: that's not a bad thing to have on your CV. It shouldn't be the only thing on your CV.

Show me the codez

This isn't essential, and you may not be able to depending on your previous employment. But if you can link to some previous code you've written (even a website where you can say "I wrote the JavaScript for this one") you'll immediately gain a boost towards an interview. We'll still give you the technical test, because unfortunately there are people who are stupid enough to try and pass off others work as their own (and it is stupid - you will get yourself burnt trying that). But you're much more likely to get to the interview stage. This is a particularly useful piece of advice for those of you just coming out of university. Can you link to your final year project? A hobby project? Your github account? If the code is good, you're instantly up there competing with candidates who on paper have years of experience over you.

Whether you show us code in advance or not, we will ask you to write something trivial during the interview. We'll make it as unscary as we can, but unfortunately enough people have come to us who cannot actually write code that we feel we have very little choice about this step. If you're nervous about this kind of thing, I would seriously suggest getting in a practice session or two with friends before getting to an interview for a development post. And be very, very wary of a company that doesn't ask you to demonstrate you can actually code.

Don't bother me with trivia, especially if it makes you look bad

Been out of school for more than 5 years? I couldn't give two figs about your grades. Unless you explicitly list the fact that you achieved a C and 3 E's at AS level. That gives me pause for thought. It's not a make or break thing, but no need to cut your own chances.

Don't fluff up your management skills (unless you want to be a manager)

We've been very borderline about interviewing several candidates because it was completely unclear from their CVs whether they actually write any code. Oh, it says "experienced C# software engineer" at the top of the CV, but if you look at the description of their last job it's all about "Team Leader", "Mentor", "SCRUM master"… Again, none of that's bad (well - maybe SCRUM master is a bit dubious) but we're not a Local Council where the only way of being "Senior" is to have management responsibility. We're hiring developers, and while we'll expect a senior developer to be a good communicator we're not expecting them to be graduates of Atlassian University. If you want to get into people management, it's a fine career path. If you want to be a developer, highlight your development skills.

Don't give in depth technical examples that give me the fear

We got a CV from someone who had recently written a desktop application that used every multithreading techniques. Really? All of them? In one app? An interesting design decision.

Fortunately for my curiosity, he proceeded to list every multithreading techniques:

  • ManualResetEvent
  • BackgroundWorker
  • Manual Dispatch

In 2015 this is not the way to highlight your expertise in writing asynchronous and concurrent reliable, maintainable code. If someone wrote code like this within the company, the code review would immediately result in some pair programming on "here's all the easier, more reliable ways you could have done this." From an applicant applying for a senior role it's an instant fail.

The problem is not here that someone didn't know how to write concurrent code: not every developer has reason to have learnt those skills. The problem is using a subject where you have very little expertise to try and boost your technical credentials.

Three things to take away here:

  1. Don't claim to be an expert on something unless you're certain that you actually are.
  2. Did something in a previous job in a way you wouldn't now? List the result, not the detail of the technique
  3. If you need ManualResetEvent you're probably doing something very wrong

Don't try and out Agile us

Yes, yes, we say we're an agile company. But frankly, a lot of stuff that people call agile is a complete waste of time, and other things we just can't do because we spend a lot of time working with customers who are not agile. At all. So, we do 15below agile. It's a nice shorthand to give you a good idea of how we generally work. And agile being as dispersed an idea as it is, that's going to be true of pretty much any company that says it's agile.

So be wary getting too carried away on your "agility". Again, don't claim to be expert if you're not: "we had a morning meeting everyday", as one of our candidates noted in his agile experience. And you're going to make me very wary if you try and come across as being an agile zealot - not because agile is bad, but because whatever it is you're a zealot about, it's not going to be "15below agile". And life's too short for getting into arguments about that kind of thing.


So, there you have. My own personal list of things that increase or decrease your chances that I'll recommend you're interviewed.

If you think that you'd be interested in working for the type of company that uses this type of criteria… well, oddly enough we're hiring at the moment. Ping me or drop a note through to jobs@15below.com.