Sunday, 5 July 2009

Reacting to the Reactive Framework: Part 3

In part one of this series, I introduced the Live Labs Reactive Framework and provided a simple example of what can be achieved when using LINQ for reactive programming. In part two I did my best to explain how my example worked. In today’s post I want to extend the example slightly. Just to reiterate, this series is not about using the Live Labs Reactive Framework as it has not yet been released. I’m exploring the idea of a reactive framework using my own implementation.

Here is my example from the previous posts:

Func<MouseEventArgs, int> slowOperation = args =>
{
    System.Threading.Thread.Sleep(3000);
    return args.X;
};

IObservable<int> observable = from md in button1.GetMouseDowns()
                              from x in slowOperation.AsAsyncObservable(md.EventArgs)
                              select x;

The idea behind this code is that the IObservable<int> represents a stream of integers that are the result of capturing the mouse down event on a button, doing some “slow processing” (really just a 3 second sleep) asynchronously, and returning the x coordinate from the mouse down event. You can then attach something to that observable like so:

Action<string> textboxUpdater = s => textBox1.AppendText(s);
observable.Attach(x => textBox1.BeginInvoke(textboxUpdater, "Mouse down: " + x + "\n"));

The attached code updates the textbox as the values bubble up through the IObservable. Unfortunately its a little more complicated than I would like because the update has to be marshalled onto the UI thread – hence the BeginInvoke call. Today I want to modify this example so that the textbox is only updated when the right mouse button was clicked. The MouseEventArgs can tell me which button was clicked, so really this is just a matter of implementing support for where:

IObservable<int> observable = from md in button1.GetMouseDowns()
                              where md.EventArgs.Button == MouseButtons.Right
                              from x in slowOperation.AsAsyncObservable(md.EventArgs)
                              select x;

Well this is a very natural way to express what I want – and the implementation is not too hard. First I create the appropriate extension method:

public static IObservable<T> Where<T>(this IObservable<T> source, Func<T, bool> predicate)
{
    return new WhereObservable<T>(source, predicate);
}

This extension method is just a wrapper call for a class. In this case, its WhereObservable<T> which takes a source IObservable, and a predicate to apply:

public class WhereObservable<T> : IObservable<T>
 {
     private readonly IObservable<T> _source;
     private readonly Func<T, bool> _predicate;

     public WhereObservable(IObservable<T> source, Func<T, bool> predicate)
     {
         _source = source;
         _predicate = predicate;
     }

     public void Attach(Action<T> action)
     {
         _source.Attach(t => { if (_predicate(t)) action(t); });
     }
 }

All I’m doing here is wrapping an inner observable so that I can check to see if the predicate applies before I let the observable event bubble up. That’s all there is to it. My example will now only update the textbox if the right mouse button was clicked.

My work on this project is available on github. To get the code as it was at the time this post was written, use this tag.

Sunday, 31 May 2009

Reacting to the Reactive Framework: Part 2

DISCLAIMER: The code in this post was the result of a big hackfest with the single goal of getting a particular use case working. I am telling you right now that I paid no attention to potential concurrency problems and that if you try to reuse any of this stuff you are just asking for trouble.

In the previous post, I explained how Eric Meijer’s recent Lang.NET presentation on the LiveLabs Reactive Framework piqued my interest. Wondering how the framework works, I decided to have a go at emulating some of the basic functionality it appears to provide. This code demonstrates the functionality I’ve implemented so far:

Func<MouseEventArgs, int> slowOperation = args =>
{
    System.Threading.Thread.Sleep(3000);
    return args.X;
};

IObservable<int> observable = from md in button1.GetMouseDowns()
                              from x in slowOperation.AsAsyncObservable(md.EventArgs)
                              select x;

Action<string> textboxUpdater = s => textBox1.AppendText(s);
observable.Attach(x => textBox1.BeginInvoke(textboxUpdater, "Mouse down: " + x + "\n"));

Today I am going to work my way through the query comprehension you can see here and do my best to explain how I got this working. Perhaps a good place to start would be to convert the query comprehension into a method chain in the same way the C# compiler does for us under the covers. Resharper can do this automatically, which is convenient:

IObservable<int> observable = button1.GetMouseDowns().SelectMany(
                    md => slowOperation.AsAsyncObservable(md.EventArgs), 
                    (md, x) => x
                    );

The first call here is to an extension method called GetMouseDowns:

public static IObservable<EventResult<Button, MouseEventArgs>> GetMouseDowns(this Button b)
{
    var wrapper = new EventWrapper<Button, MouseEventArgs>();
    b.MouseDown += wrapper.Handle;
    return wrapper;
}

So far, this is relatively straightforward. The GetMouseDowns extension method creates an EventWrapper, and wires that EventWrapper up to the MouseDown event on the button. You can see that the wrapper is being returned as an IObservable of an EventResult. Here is the code for these:

public interface IObservable<T>
{
    void Attach(Action<T> action);
}
public class EventResult<TSender, TArgs>
{
    public EventResult(TSender sender, TArgs args)
    {
        Sender = sender;
        EventArgs = args;
    }

    public TSender Sender { get; private set; }
    public TArgs EventArgs { get; private set; }
}
public class EventWrapper<TSender, TArgs> : IObservable<EventResult<TSender,TArgs>>
{
    private List<Action<EventResult<TSender, TArgs>>> _attached = new List<Action<EventResult<TSender, TArgs>>>();

    public void Handle(object sender, TArgs e)
    {
        foreach (var action in _attached)
            action(new EventResult<TSender,TArgs>((TSender)sender, e ));
    }

    public void Attach(Action<EventResult<TSender, TArgs>> action)
    {
        _attached.Add(action);
    }
}

Now there is some really naive code here. What would happen if someone called Attach while we were in the middle of handling the event? It would crash, because the list of actions to be called would be modified while it was being iterated over. In general, the code for the EventWrapper feels bad. I am sure it can be done much better, but it works for now.

So the result of the GetMouseDowns method is an EventWrapper that will call the attached methods when the mouse down event occurs, and this is exposed as an IObservable. SelectMany is then called on that IObservable. This is another extension method:

public static IObservable<TResult> SelectMany<TSource, TCollection, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
    return new SelectManyObservable<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
}

So how on earth did I arrive at this method? Its quite simple actually – I stole its signature from the SelectMany extension method implemented on IEnumerable. The interesting thing about LINQ query comprehensions is that they actually don’t have a dependence on IEnumerable or IQueryable. Instead they depend on the existence of particular methods with the appropriate signature such as Select, SelectMany, Where, GroupBy, etc. By writing these extension methods for IObservable, I can then write query comprehensions against IObservables.

Once its established that my SelectMany borrowed its signature from the appropriate extension method on IEnumerable, there isn’t much more to know about it. You can see that all it simply does is return a SelectManyObservable that wraps the passed arguments. What is the SelectManyObservable exactly? Well, here is the code:

public class SelectManyObservable<TSource, TCollection, TResult> : IObservable<TResult>
{
    private readonly IObservable<TSource> _source;
    private readonly Func<TSource, IObservable<TCollection>> _collectionSelector;
    private readonly Func<TSource, TCollection, TResult> _resultSelector;

    public SelectManyObservable(IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
    {
        _source = source;
        _collectionSelector = collectionSelector;
        _resultSelector = resultSelector;
    }

    public void Attach(Action<TResult> action)
    {
        _source.Attach(
            s => _collectionSelector(s).Attach(
                c => action(_resultSelector(s, c))
            )
        );            
    }
}

So this class simply wraps an underlying IObservable, and when methods are attached to the SelecyManyObservable, it actually gets attached to the underlying IObservable. The funny thing about this code is that it practically wrote itself. It was basically a matter of just figuring out how the underlying observable, collectionSelector, resultSelector and attached action related to each other and then calling them accordingly. It felt like solving a 4 piece jigsaw puzzle with only 1 solution.

Before the explanation of the query comprehension is complete, there is one more extension method that requires explanation:

public static IObservable<TResult> AsAsyncObservable<TInput, TResult>(this Func<TInput,TResult> funcToObserve,TInput input)
{
    return new AsyncWrapper<TInput, TResult>(funcToObserve, input);
}

This pattern should look familiar. Its like the SelectMany in that it simply returns a wrapper object that takes all the method arguments as parameters. The signature however, wasn’t borrowed from the framework. The point of this method is to allow the user to convert an anonymous delegate or lambda expression into an IObservable. Now I hope you packed the goggles I mentioned in my previous post, because AsyncWrapper is really nasty:

public class AsyncWrapper<TInput, TResult> : IObservable<TResult>
{
    private List<Action<TResult>> _attached = new List<Action<TResult>>();

    public AsyncWrapper(Func<TInput, TResult> funcToObserve, TInput input)
    {
        funcToObserve.BeginInvoke(input, CompletedCallback, null);
    }

    public void Attach(Action<TResult> action)
    {
        _attached.Add(action);
    }

    private void CompletedCallback(IAsyncResult asyncResult)
    {
        TResult calculatedValue = ((Func<TInput, TResult>) ((AsyncResult) asyncResult).AsyncDelegate).EndInvoke(
            asyncResult);

        foreach (var action in _attached)
            action(calculatedValue);
    }
}

It might not seem so bad, until you look at what the constructor is doing. When the AsyncWrapper is created, it fires off the function to observe. Now when that function completes, the callback will be invoked, and as a result all the attached actions will also be invoked. The reason why this is all so heinous is that the actions will have to be attached AFTER the function to observe is invoked, but before it completes. As a result, I am fairly sure that if we changed the slow asynchronous operation to be much faster, then this code would stop working. Surely a better solution can be found, and I do hope to attend to this later.

So that covers all the code that makes my example work. The nice thing about this approach is the composability. It is convenient to be able to work with enumerables using select, where, etc and the same is true for observables. I am really looking forward to getting my hands on the Reactive Framework code. In the mean time, I’ll continue to experiment. In the next post I’ll extend this example, starting with adding support for ‘where’ operations.

Tuesday, 26 May 2009

Reacting to the Reactive Framework: Part 1

Last night I managed to get some code working and I was very excited, but it was far too late to start writing a blog post. Here is the code:

Func<MouseEventArgs, int> slowOperation = args =>
{
    System.Threading.Thread.Sleep(3000);
    return args.X;
};

IObservable<int> observable = from md in button1.GetMouseDowns()
                              from x in slowOperation.AsAsyncObservable(md.EventArgs)
                              select x;

Action<string> textboxUpdater = s => textBox1.AppendText(s);
observable.Attach(x => textBox1.BeginInvoke(textboxUpdater, "Mouse down: " + x + "\n"));

This code is sitting inside a very simple windows form. The form has a button and a textbox. When the button is clicked, a message is written to the textbox about 3 seconds later, relaying the relative X coordinate of the mouse when the button was clicked. The 3 second delay represents some sort of slow asynchronous operation, currently simulated with a simple Thread.Sleep(). Because the slow operation is done on a different thread, we have to use Control.BeginInvoke() to get the textbox to update on the UI thread. GetMouseDowns() is an extension method on Button that helps set the whole thing up by returning an IObservable that is wired to the MouseDown event.

So at this point you might be wondering what this is all about. To get the full story, I encourage you to watch Eric Meijer’s video on the LiveLabs Reactive Framework (direct wmv link). In this very enjoyable presentation, Eric gives us a run down the Reactive Framework, which appears to be a set of libraries that unite various types of “reactive” operations under a common pair of interfaces, IObserver<T> and IObservable<T> which are then integrated into LINQ. I found the presentation to be quite a tease. Erik shows just enough to give you an idea of what the Reactive Framework is all about, but he skims over the implementation details quite lightly. I ended up watching the thing a couple of times, trying to wrap my head around the idea of LINQ query comprehensions (e.g. from x in y select x.ID) operating against non enumerable/queryable types. In particular, I started wondering whether I could implement something like the code from this slide:

image

As you can see, my code at the top is not too dissimilar from Erik’s code here. Erik’s example is a web page with dictionary suggest on a textbox. When the user enters a character into the textbox, the dictionary suggest runs asynchronously against the input entered so far and when a return value is received it is rendered as html.

There is certainly quite a lot regarding the Reactive Framework that I don’t understand. I’ve been unable to find any resources beyond Erik’s talk – certainly the code doesn’t seem available anywhere. So far I don’t even understand how IObserver fits in. Can YOU see anything that might implement IObserver in the above slide? But in any case, the idea is intriguing, and trying to figure out how to do this myself is teaching me quite a bit about LINQ. In the next post, I’ll do my best to explain how the implementation works. Don’t forget your goggles, this is some pretty hacky code coming up.

Wednesday, 29 April 2009

A Fluent NHibernate update

Since James has announced the latest happenings in the ongoing saga of moving Fluent NHibernate to using a semantic model, I thought a companion post might be appropriate.

My first post on the Fluent NHibernate rewrite is as good a place to start as any. In it I explained the limitations of the existing implementation and outlined my strategy for dissolving those limitations. My branch differs from the trunk by separating the fluent interface from the mapping model. The fluent interface manipulates the underlying model, and a family of visitors build a Hbm object graph that represents that underlying model. That object graph is serialized to xml and then passed to NHibernate. This graph consists of classes that are generated from the NHibernate mapping schema, so the serialization step is all automatic and works flawlessly.

The use of the visitor pattern allows for two things. One, the mapping model is not tied to any particular output format. Sure we pass NHibernate xml today, but tomorrow it would be nice to pass it the Hbm object graph directly so it can skip the xml schema validation step. The day after it would be nice to pass it a prebuilt NHibernate.Mapping graph, which is an idea that Tuna Toksoz was exploring from within my branch. Secondly, the visitor implementation allowed for powerful manipulations of the mapping model that would otherwise be difficult. I talked more about the visitor implementation here.

Sure, passing NHibernate its mappings in a format other than xml would be nice some day, but there was another reason why I chose to use a Hbm graph instead of directly writing xml. Basically, its much harder to go off the rails when working with the Hbm objects. One example is that the NHibernate schema is finicky about element ordering and you simply don’t have to worry about this when working with Hbm objects.

As time went on the code base grew, things changed, but slow and steady progress was made. The problem is that slow and steady doesn’t always win the race – specifically in the case where the goalpost is moving as fast or faster than you! This is the classic rewrite problem. I’m sure you are familiar with it – its why all the well respected software professionals tell you that rewriting your app is a fools errand. And don’t get me wrong, I am in agreement here. I approached my work to rewrite Fluent NHibernate as a prototyping exercise - “one possible future” if you will. As the work continued I would discuss our long term goals with James and for a while we found ourselves hoping that we could replace the existing trunk with my branch, if only we could “catch up” to the trunk functionality. Of course this sort of thinking was dangerous, and the consequences are well described in James’s post. My intentions, while good, have lead to a lack of progress on the Fluent NHibernate trunk and this is simply not a healthy place to be.

James asked me whether I could see a way to merge the two code bases. Basically inject my model into the existing guts of the trunk. I told him I couldn’t see a way how, but I encouraged him to try. The problem, I’m sure you’ve already guessed, is that I was too “caught up” in my code and simply not prepared to make sacrifices. This is why James managed something that I could not – he merged my branch into the trunk code under an “integration”  branch, with all the existing trunk tests passing. Its not pretty, but I suspect that it represents the best direction to work from. We can now do what the experts tell us to do and refactor, rather than rewrite.

So what were the sacrifices? The main one is the Hbm object graph approach. Fluent NHibernate will only be capable of spitting out xml for the near future. Lets face it, its not a huge loss. Plus I say near future because the visitor implementation survived, so there is no reason why we couldn’t later start retrofitting my Hbm code in. I am yet to take full stock of the “casualties”, but I expect that everything that has been lost in the merge can be regained through a gradual process of refactoring and reintroducing code and ideas from my branch. It will be fun!

Finally I want to use this post as an opportunity to thank James for all his amazingly hard work on this great project. We don’t always see eye to eye but the thing that I often remind myself is that time and again he has proven to me that he has his finger on the pulse of our users and can see how this project can best fulfil their needs. Please keep it up James.

Monday, 27 April 2009

Legacy code: a follow up

A few weeks back I wrote a post on Working Effectively with Legacy Code, a book by Michael Feathers. At the time I lamented that even though I accepted Michael’s definition of legacy code (code without tests), I wasn’t doing much about it – I hadn’t written any tests at work. Today I wanted to follow up on this because the last two weeks have gone much better – I’ve been writing unit tests. I was given the job of rewriting a particularly hairy module and this was simply too good an opportunity to pass up. I’m not doing TDD yet, and I certainly haven’t written as many tests as I would like, but its a start.

Rather than using a mocking framework, I’ve been hand rolling stubs. I believe that the other developers will have an easier time understanding the tests if I use manual stubs. Mocking frameworks are certainly convenient but as Michael demonstrates in his book, they are not necessary per se. So far I haven’t found this particularly painful and I think its a sound approach for introducing automated unit testing. I must admit that the fact that I am working on a .NET 2.0 project made this decision easier. I learned Rhino Mocks using the .NET 3.5 API and I think I would have a hard time going without the sweetness that lambda expressions provide.

Writing that very first test is a bit of a barrier, but its only a mental one. I was fortunate to have a nice piece of work come along and give me a push. Hopefully it will not be necessary the next time I find myself faced with legacy code – I intend to write that first test without a moment of hesitation. Its all downhill from there.

Monday, 13 April 2009

Working Effectively with Legacy Code

Working Effectively with Legacy Code (Robert C. Martin Series)

Today I finished reading Working Effectively with Legacy Code by Michael Feathers. If you are not familiar with this book, you might be wondering if I’ve somehow been roped into maintaining some sort of 10 year old VB6 application -fortunately this is not the case. But I am indeed working on a legacy application – at least, it is legacy by Michael’s rather unique definition. Michael defines legacy code as code that is not under test, specifically unit tests. By Michael’s definition, virtually all of the code I have written during my career was legacy from the day it was born, and when I reflect on it, this seems like a fair statement. Here is a short excerpt from the preface:

Code without tests is bad code. It doesn’t matter how well written it is; it doesn’t matter how pretty or object-oriented or well-encapsulated it is. With tests, we can change the behaviour of our code quickly and verifiably. Without them, we really don’t know if our code is getting better or worse.

It doesn’t matter how clean and refactored my code was – developers that had to maintain it were forced to do so with uncertainty. It is specifically that element of uncertainty that I associate with the legacy code experience.

The book uses a FAQ format, with chapter titles such as:

  • I need to make a change. What methods should I test?
  • I can’t get this class into a test harness.
  • This class is too big and I don’t want it to get any bigger.
  • I need to make a change but I don’t know what tests to write.

It does a great job of illustrating refactorings that let you break dependencies so you can get the code under test. These refactorings are designed to be performed safely without tests so you can get the tests written and then move on to more significant refactorings. The book also does a great job of tackling the mechanics of writing the tests themselves.

I think the book could have been better named. Ayende says that it should be mandatory reading for people that write code for a living. I agree with him, but the title does not communicate this. In general I found it very readable and relatively quick to get through, and the lessons the book offers are profound.

So the obvious question is whether it has changed the way I’ve been writing code. Well unfortunately, I wrote a bunch of legacy code just last week! By night I revel in the freedom that my unit tests give me as I work on Fluent NHibernate, but by day I continue to work in a manner that Uncle Bob would consider unprofessional. Why?

Unfortunately the book doesn’t have a chapter called “I’m all alone, nobody else is convinced that writing unit tests is worthwhile. Is it worth starting if its just me doing it?”. Nor does it have a “This is just a quick fix for someone else’s broken code, I’ll write tests when the –real- work begins” chapter (its a weak argument but I’ve found it an easy trap to fall into). The closest the book comes is the very last FAQ chapter: “We feel overwhelmed. It isn’t going to get any better”. But at less than 2 pages, it didn’t quite deliver what I needed to hear.

I’m finding it difficult to take that first step and add that 55th project to the solution (yeah…) so I can write some tests. Part of it is procrastination, but part of it is fear. I believe these ideas have value and I don’t want to screw it up. But simply “waiting until the time is right” is the refrain of the procrastinator.

This makes me feel that Working with Legacy Code is a great book, but not an entirely complete package. It gives you the tools and techniques but assumes that the reader can simply read it and run with it. Michael developed these techniques as he worked with teams that heeded his advice and were prepared to follow his lead. A piece of the puzzle is missing because Michael has been the consultant for so long.

Maybe this criticism is unfair. People can write books full of advice, but its up to the reader to start putting that advice into practice. A new work week begins tomorrow, perhaps I’ll add that 55th project before I do anything else tomorrow morning.

Monday, 9 March 2009

Supporting multiple NHibernate versions in Fluent NHibernate semantic model

My Fluent NHibernate semantic model rewrite is designed to support multiple versions of NHibernate simultaneously. At the moment, I support NH 2.0.1GA and 2.1.0.1001 (this was a trunk snapshot). My goal is to support the latest official release and to keep as up to date with the trunk as possible; time will tell how well this pans out.

The semantic model rewrite makes heavy use of classes that are generated from the NH mapping schema. These classes are all prefixed with Hbm, so I am in the habit of calling them “Hbm*” classes. Here is some example code that builds a HbmKey representation of a KeyMapping:

public override void ProcessKey(KeyMapping keyMapping)
{
    _hbm = new HbmKey();

    if (keyMapping.Attributes.IsSpecified(x => x.Column))
        _hbm.column1 = keyMapping.Column;

    if (keyMapping.Attributes.IsSpecified(x => x.ForeignKey))
        _hbm.foreignkey = keyMapping.ForeignKey;

    if (keyMapping.Attributes.IsSpecified(x => x.PropertyReference))
        _hbm.propertyref = keyMapping.PropertyReference;

    if (keyMapping.Attributes.IsSpecified(x => x.CascadeOnDelete))
        _hbm.SetCascadeOnDelete(keyMapping.CascadeOnDelete);
}

Because the NH mapping schema changes from version to version, the public interface for these classes also changes from version to version. See that “column1” property? Its entirely possible it was called “column” in an earlier version of NH. Obviously, if it were to change back to “column” tomorrow, this code would no longer compile. Given this, how can Fluent NH hope to simultaneously support multiple NH versions? The answer is to put any version specific code in a separate assembly.

Today I will fix a NH2.1 incompatibility that I introduced a few days ago when adding the ability to specify the column name for a property. Here is the code I wrote while working against NH2.0.1:

public override void ProcessProperty(PropertyMapping propertyMapping)
{
    _hbm = new HbmProperty();
    _hbm.name = propertyMapping.Name;

    if(propertyMapping.Attributes.IsSpecified(x => x.IsNotNullable))
        _hbm.SetNotNull(propertyMapping.IsNotNullable);

    if (propertyMapping.Attributes.IsSpecified(x => x.Length))
        _hbm.length = propertyMapping.Length.ToString();

    if (propertyMapping.Attributes.IsSpecified(x => x.ColumnName))
        _hbm.column1 = propertyMapping.ColumnName;
}

The very last line is the one to watch here. You can see its setting the “column1” property. This worked fine against NH2.0.1 but when I ran my rake script to switch over to NH2.1 today, this code no longer compiled - the property is now called “column”. As I mentioned above, my strategy for dealing with this problem is to use version specific assemblies. Here is the Fluent NH solution:

image

The two “Versioning” projects are where the version specific code goes – they each reference their own version of NHibernate. Each project contains the same set of extensions methods, each method implemented slightly differently depending on the versioning requirements. The two projects share the same namespace and output an assembly with the same name (FluentNHibernate.Versioning) and to the same location. Neither project is included in the default build configuration, so they have to be built explicitly. The act of building one of these versioning projects will make it “active” because the assembly is output to the same location that the FluentNHibernate project is referencing.

With the background out of the way, lets fix the problem with with “column1” property on HbmProperty. First I open the Versioning.NH20 project, find the HbmPropertyExtensions and add an extension method:

public static class HbmPropertyExtensions
{
    ...
public static void SetColumn(this HbmProperty hbmProperty, string column) { hbmProperty.column1 = column; } }

I then modify the code to call the extension method:

if (propertyMapping.Attributes.IsSpecified(x => x.ColumnName))
    _hbm.SetColumn(propertyMapping.ColumnName);

I compile the Versioning.NH20 project to make sure its active and run my tests. I already have a test that is verifying this implementation – here it is:

[Test]
public void Should_write_the_attributes()
{
    var testHelper = new HbmTestHelper<PropertyMapping>();
    testHelper.Check(x => x.Name, "test").MapsToAttribute("name");
    testHelper.Check(x => x.Length, 50).MapsToAttribute("length");
    testHelper.Check(x => x.IsNotNullable, true).MapsToAttribute("not-null");
    testHelper.Check(x => x.ColumnName, "thecolumn").MapsToAttribute("column"); <--- HERE
    var writer = new HbmPropertyWriter();
    testHelper.VerifyAll(writer);
}

Because this test verifies that a certain property is written to the correct xml attribute, it works for both versions of NH. Regardless of what the property is called on the Hbm class, its written to the “column” attribute.

The tests all pass, so I switch to NH2.1 using my rake script and move to the Versioning.NH21 project. Again, I add an extension method:

public static class HbmPropertyExtensions
{
    ...
public static void SetColumn(this HbmProperty hbmProperty, string column) { hbmProperty.column = column; } }

This looks almost the same as the code above, but notice that the “1” is gone. I compile the Versioning.NH21 project to make sure its active and run the tests. They all pass!

So far, all the versioning issues I’ve ran into were easily fixed like the one above. Lets hope they are all this simple!