On a quest for the silver bullet..

How I use the Glue mapping framework

Glue is a general purpose, bidirectional automatic mapping framework for the .Net platform, with strong verification and testing tools.

I’m actively developing it. I’m also actively using it. In this post I’ll share my experience as a user of Glue, and how easy it is to set up the mappings using TDD.

The example

We want to create a mapping between DomainPerson and GuiPerson, listed here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class DomainPerson
{
    public int Id { get; private set; }
    public String Name { get; set; }
    public DomainAddress Address { get; set; }
}
 
public class DomainAddress
{
    public String StreetAddress { get; set; }
    public int ZipCode { get; set; }
    public String City { get; set; }
    public String Country { get; set; }
}
 
public class GuiPerson
{
    public int Id { get { return 0;} set { return;} }
    public String Name { get; set; }
    public String StreetAddress { get; set; }
    public int ZipCode { get; set; }
    public String City { get; set; }
    public String Country { get; set; }
}

Making sure all properties are related

What I test first is that all the properties are related (or actively ignored). This makes it easy to later detect changes in the classes we map between. It also makes it easy for us to see what properties we have to handle.

But first, in traditional TDD style, lets start with writing a failing test. The test should verify that all properties on GuiPerson are either related or actively ignored. The test looks like this:

1
2
3
4
5
[Fact]
public void AsserAllPropertiesRelated()
{
	mapping.GetRelationsVerification().AssertAllPropertiesRelated<GuiPerson>();
}

and, as this will not compile, let’s create the actual mapping:

1
mapping = new Mapping<DomainPerson, GuiPerson>();

It compiles, but as expected, it fails. We have created a mapping, but nothing is related. A nice feature with Glue is that it tries to be as informative as possible when it fails. Look at the exception we receive when running this test:

Not all properties are related (or ignored): Id, Name, StreetAddress, ZipCode, City, Country

It tells us what properties we need to handle. This makes my job easy. I’ll just have to relate (or ignore) all the properties reported in the exception:

1
2
3
4
5
6
7
mapping.Relate(domain=>domain.Id,gui=>gui.Id);
mapping.Relate(domain => domain.Name, gui => gui.Name);
 
var addressMapping = new Mapping<DomainAddress, GuiPerson>();
addressMapping.AutoRelateEqualNames();
 
mapping.Flatten(domain=>domain.Address,addressMapping);

Running the test, I get another Exception:

Glue.GlueException : The relation between ‘Id’ and ‘Id’ has atleast one readonly property, and can not be related TwoWays

Ah, fair enough, it went a bit fast there. I related all properties, but I didn’t check if any where readonly. Luckily, Glue tells us this early. I’ll make this change:

1
mapping.RelateTowardsRight(domain => domain.Id, gui => gui.Id);

And when I run the test again, it goes green. Now all properties are related, and we are protected from future changes.

Make sure the mapping actually works

But will it really work? We can also easily check if the actual values can be set on the target object. You should do this. I always do. So, lets start with another test:

1
2
3
4
5
[Fact]
public void AssertMappingWorks()
{
    mapping.GetMapperVerification().AssertMapsCorrectlyTowards(new GuiPerson());
}

Running this test, we get an Exception:

Glue.GlueException : Failed properties: Id (Failed to set value)

Ah, it detected that Id on GuiPerson is totally unable to set. Ok, lets say that this is supposed to be this way. That means we should not map Id towards GuiPerson. That means that we must remove this:

1
mapping.RelateTowardsRight(domain => domain.Id, gui => gui.Id);

Running the tests again makes AssertMappingWorks gets green, but now AsserAllPropertiesRelated got red again. That is because we have not related Id on GuiPerson. But since we do not want to relate it, we ignore it, to signal that we actively have made that choice. We do it like this:

1
mapping.IgnoreTowards<GuiPerson>(gui=>gui.Id);

GlueRunning the tests, they both are green, and now we know that we have a working mapping, which also are protected from failing on future changes.

Note that this example only tests the mapping and relations towards GuiPerson, in a bidirectional mapping scenario I advice to write the same two tests towards DomainPerson.

This is how I do it, and it works great for me. Hope you liked it. To learn more about Glue, and to download it, go to the Glue homepage at Codeplex

- Tore Vestues

September 2nd, 2009 at 13:33 (606)


3 Responses to “How I use the Glue mapping framework”

  1. Anders Hammervold Says:

    This seems to be the mapping framework i have been waiting for.

    The combination with test-verifiable mapping to ensure that the mapping doesnt break is very good.

    Checking it out now.

  2. Alex York Says:

    We are using Glue in our current project in this scenario:

    The Data Access Layer uses LINQ to SQL, but we don’t want the auto-generated LINQ entities to go anywhere outside the DAL (they “know too much”). We map them to our real objects that we want to use in our business layer. We were doing this mapping manually before – but Glue saves us a lot of monkey work in this way.

    It’s working pretty well for us so far, so thumbs up.

  3. Tore Vestues Says:

    Thanks for great feedback. Feel free to contact me directly if you need support on Glue, or have suggestions for new features.

Leave a Reply