Dan Newcome, blog

I'm bringing cyber back

When to write a library

with 4 comments

I’ve been meaning to write this post for a while. There have been a lot of instances in my work where the debate comes up about when to start abstracting code. There inevitably comes a time where a bit of code gets copied and tweaked enough times that it screams out to be put into a common library. However it has been my experience that programmers are still reluctant to take on the task of creating a common code base. Actually I’ve also noticed that many times programmers think that “code reuse” means just copying some of the files out of a previous project when starting a new one.

Some of these quick and dirty techniques are expedient initially, but we need to move past them to make any real progress on the problems that we work on. In my experience, creating modular code allows the code to be reasoned about more easily.

However, there are some downsides to creating libraries. It takes a non-trivial amount of work to create and maintain a piece of shared code. Once a piece of code is used in many places, it becomes nearly impossible to test the code without dedicated tests that cover all intended use cases. This means that even if the code is already written as a de facto library, lots of supporting code needs to be written in order to make the library maintainable.

Existing client code needs to be re-factored to use the new library going forward. This step is not totally necessary, as many times older code bases can be maintained as legacy code bases separately and only upgraded if other changes are necessary later on.

So this leads us to the question, when does it make sense to write a library? I’d say that when the pain of not having the code centrally located becomes significant. In the past I was a purist and I would have created some library right away, but I think that it takes some time to even figure out what the API should be so I think it makes sense now to intentionally experience some pain of having maybe three or four different versions of the code before consolidating the code.

Unfortunately, I think some languages make the unit of code deployment too large and cumbersome. In the .NET framework I’d argue that the Assembly is too cumbersome for many things. There are many times where I want a single interface to be independent and available separately but I would have to put it in its own assembly in order to reference it separately. It’s easy to fall into DLL hell with tens or even hundreds of assemblies. Each assembly carries the overhead of a separate build file or Visual Studio project file. I think there needs to be a lighter weight way of sharing code in .NET.

This post rambled on a bit, but I’m getting started on a series of posts on software engineering, so I wanted to kick things off with some problems that I have faced in the past, of which this is one of the most difficult.

Advertisements

Written by newcome

December 13, 2011 at 10:30 pm

Posted in Uncategorized

4 Responses

Subscribe to comments with RSS.

  1. Aargh I think your blog/user error just nuked a really long comment I wrote 😦

    To summarise:

    1 use Nuget + myget.org + teamcity to simplify dll hell

    2 The job of library extraction is not complete if your new libraries depend on one another. If they do, you need to create an extension point. When an app needs to consume both, it should be responsible for hooking them together in a simple way.

    Harry McIntyre (@mcintyre321)

    December 14, 2011 at 5:34 am

  2. Hi Harry, thanks for the comments, sorry that WordPress ate your previous post.

    I’ve used Nuget a bit, and I think that this is a great tool. The thing that boggles my mind is how long it took for someone to actually address this problem. I have my own assembly management scripts that I’ve been using for years to manage dependencies, but now nuget makes all that redundant.

    As far as library extraction, what ends up happening in many cases is that there is one assembly with an interface or two that establishes the direct dependencies. Other assemblies will implement these interfaces. I think this is what you meant by extension points?

    newcome

    December 14, 2011 at 10:06 am

  3. Yep that’s what I’m talking about, although I’ve been tending to avoid using interfaces recently, as not only do you then tend to have an extra glue assembly (e.g. NHibernate..ByteCode.Castle, or the various CommonServiceLocator implementation libraries.) on top of the two libraries, you also need to register that assembly somewhere in your application. For me, thats a lot of boilerplate.

    Instead I’ve been using (would you believe! 🙂 delegates as extension points, which removes the need for the implemented interface

    e.g. I have two libraries, FormFactory (which generates forms by reflecting over object instances, a bit like MVC Editor Templates) and Harden, which is used to wrap objects with dynamic guard clauses. In conjunction you can use them to create highly dynamic web UI.

    FormFactory uses Harden to determine which properties to generate UI. In order to break the dependency, I expose something like

    public class FormFactory
    {
    public delegate bool FilterRule(object objectToInspect, MethodInfo methodBeingCalled);
    public List Rules {get;} //this is a registry of extension points that can be added to
    }

    this lets me hook the libraries together in my app like so

    var ff = new FormFactory();
    var hardener = new Hardener();
    ff.Rules.Add((o, mi) => hardener.Harden(o, mi));

    so there is no need to reference an assembly containing a single implementation of

    interface IFilterRule
    {
    bool FilterRule(object objectToInspect, MethodInfo methodBeingCalled);
    }

  4. Hey Harry, good discussion.

    Delegates are a good idea for allowing extension. In the case of validators, they are perfect. Another thing I end up doing sometimes is using reflection to load an assembly that I don’t want to depend on strictly. Logically equivalent to Dependency Injection, although very much simplified compared to Spring, etc.

    The limitation that I run into is still shared custom types, even if they are just POCO type of data containers. A lot of the time I end up using reflection and untyped collections or convoluted generics to dance around the type system and it feels kind of dirty/pointless. It’s disappointing to have to fight the very system that is supposed to be helping you to be more productive.

    newcome

    December 14, 2011 at 11:11 am


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

%d bloggers like this: