Three new featurelets for Fluent NHibernate

Lately I have been using Fluent NHibernate and NHibernate respectively for my ORM (Object-Relational Mapping) when working on my top secret pet project. Simply put – it’s great. Mapping is done using a fluent C# interface which makes use of lambda expressions for referencing properties instead of strings (check my previous post for more info) so the domain model is safe to refactor because the mapping will be kept up-to-date too.

I spend some time hacking on Fluent NHibernate to add three little features I needed for my integration unit testing via Fluent NHibernate’s PersistenceSpecification. They all currently live in my GitHub(also used by Fluent NHibernate) fork here and have all been submitted upstream. UPDATE: The changes are as of now (21.12.2009) officially part of Fluent NHibernate. I can only hope you will find them useful as well.

PersistenceSpecification: More Informational Error Reporting

Particularly useful to troubleshoot failing mapping integration unit tests when a property check fails it will print both expected and actual types of the values. Also notice that chained properties (object.PropA.PropB) are now supported as well:

For property ‘Nutrition.Calories’ expected ‘400′ of type ‘System.Int32′ but got ‘400′ of type ‘System.Single’.

instead of:

Expected ‘400′ but got ‘400′ for Property ‘NutritionCalories’

PersistenceSpecification: Entity Components Property Testing

It is now possible to test entity component properties. For example given this domain model:

public class Food
{
    public Food ()
    {
        Nutrition = new NutritionInfo ();
    }

    public virtual NutritionInfo Nutrition { get; protected set }
    public virtual int Id { get; set; }

}

public class NutritionInfo
{
    public virtual float? Fat { get; set; }
}

and this mapping:

public class FoodMap : ClassMap<Food>
{
    public FoodMap ()
    {
        Id (food => food.Id)
            .GeneratedBy.Native ();

        Component<NutritionInfo> (food => food.Nutrition,
            mapping => {
                mapping.Map (nutrition => nutrition.Fat)
                    .Nullable ();
            }
        ).Access.BackingField ();
    }
}

One can now use this in unit tests:

[TestMethod]
public void Food_Mapping ()
{
    new PersistenceSpecification<Food> (Session)
    .CheckProperty (food => food.Id, 1)
    .CheckProperty (food => food.Nutrition.Fat, 40f) // <-- This one
    .VerifyTheMappings ();

}

Prior to my patch this wasn’t possible because Fluent Nhibernate PersistenceSpecification did not support chained properties and was trying to set a Fat property on the food object. Note that this is useful only for components and not references. For the latter .CheckReference (…) should be used which will also commit the reference to the Database before doing anything else.

PersistenceSpecification: IEqualityComparer for Individual Properties

Given the setup from above it is now possible to set an IEqualityComparer per property, e.g.:

[TestMethod]
public void Serving_Mapping ()
{

    new PersistenceSpecification<Food> (Session, new EqualityComparerForAllProperties ())
    .CheckProperty (food => food.Id, 1)
    .CheckProperty (food => food.Nutrition.Fat, 40f, FloatEqualityComparer.Instance)
    .VerifyTheMappings ();
}

If there is no comparer set for the property it will fall back to using the EqualityComparerForAllProperties and if that is not specified it will just use Object.Equals.

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Dec 13th, 2009 (Views: 194)
Categories: Coding

How to avoid passing property names as strings using C# 3.0 Expression Trees

Referencing property names via strings is evil. Consider this simplistic example:

private int _myProperty;

public int MyProperty
{
    get { return _myProperty; }
    set {
        _myProperty = value;
        NotifyPropertyChanged (this, "MyProperty")
    }
}

// Somewhere in a different project or file...
private void NotifyPropertyChanged (object sender, string propertyName)
{
    if (propertyName == "MyProperty")
        Console.WriteLine ("Property Changed");
}

If at some point the property gets renamed the code will compile fine but a bug will be introduced as all those strings that contain the property name will remain unchanged. Evil.

So I have been toying with NHibernate lately and yesterday I was writing some repositories. Let’s assume that theoretically they look like this:

public class Repository <TEntity>
{
    public virtual TEntity FindById (object id)
    {
        ...
    }
}

public class UserRepository : Repository<User>
{
    public IList<User> FindByName (string name)
    {
        // query code
    }

    public IList<User> FindByEmail (string email)
    {
        // query code
    }
}

Both FindByName and FindByEmail in UserRepository will in theory contain the same queries but with different parameters. However I don’t really want to have to write individual queries so I considered a utility method:

public class Repository <TEntity>
{
    public virtual TEntity FindById (object id)
    {
        ...
    }

    protected virtual IList<TEntity> FindByProperty (string propertyName, object value)
    {
        string columnName = NHibernateUtil.GetPropertyColumnName<TEntity> (propertyName);

        // Query here, e.g: "SELECT .... WHERE .... columnName = value" , etc.
    }
}

public class UserRepository : Repository<User>
{
    public IList<User> FindByName (string name)
    {
        return base.FindByProperty ("Name", name);
    }

    public IList<User> FindByEmail (string email)
    {
        return base.FindByProperty ("Email", email);
    }
}

Again this is very bad code and I hated the idea of it, so I sat down and started thinking. I remembered reading somewhere about C# 3.0 Expression Trees so I did some research. When using the special Expression type this seems to tell the compiler to create and expose an AST to us of e.g. a lambda function’s body, so if we pass a property reference expression we can parse the AST and extract the property name from there.

The theory in practice:

public class UserRepository : Repository<User>
{
    public IList<User> FindByName (string name)
    {
        return base.FindByProperty (user => user.Name, name);
    }

    public IList<User> FindByEmail (string email)
    {
        return base.FindByProperty (user => user.Email, email);
    }
}

public class Repository <TEntity>
{
    public virtual TEntity FindById (object id)
    {
        ...
    }

    protected virtual IList<TEntity> FindByProperty (Expression<Func<TEntity, object>> propertyRefExpr,
                                                     object value)
    {
        string propertyName = GetPropertyName (propertyRefExpr);

        // Query code
    }

    private string GetPropertyName (Expression propertyRefExpr)
    {
        if (propertyRefExpr == null)
            throw new ArgumentNullException ("propertyRefExpr", "propertyRefExpr is null.");

        MemberExpression memberExpr = propertyRefExpr.Body as MemberExpression;
        if (memberExpr == null) {
            UnaryExpression unaryExpr = propertyRefExpr.Body as UnaryExpression;
            if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert)
                memberExpr = unaryExpr.Operand as MemberExpression;
        }

        if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property)
            return memberExpr.Member.Name;

        throw new ArgumentException ("No property reference expression was found.",
                         "propertyRefExpr");
    }
}

Also as a helper class:

public static class PropertyUtil
{
    public static string GetPropertyName<TObject> (this TObject type,
                                                   Expression<Func<TObject, object>> propertyRefExpr)
    {
        return GetPropertyNameCore (propertyRefExpr.Body);
    }

    public static string GetName<TObject> (Expression<Func<TObject, object>> propertyRefExpr)
    {
        return GetPropertyNameCore (propertyRefExpr.Body);
    }

    private static string GetPropertyNameCore (Expression propertyRefExpr)
    {
        if (propertyRefExpr == null)
            throw new ArgumentNullException ("propertyRefExpr", "propertyRefExpr is null.");

        MemberExpression memberExpr = propertyRefExpr as MemberExpression;
        if (memberExpr == null) {
            UnaryExpression unaryExpr = propertyRefExpr as UnaryExpression;
            if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert)
                memberExpr = unaryExpr.Operand as MemberExpression;
        }

        if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property)
            return memberExpr.Member.Name;

        throw new ArgumentException ("No property reference expression was found.",
                         "propertyRefExpr");
    }
}

As you can see it contains two generic methods that operate either on types:

string propertyName = PropertyUtil.GetName<User> (u => u.Email);

or instances:

User user = GetUser();
string propertyName = user.GetPropertyName (u => u.Email);

Great, isn’t it? And safe to refactor.

Of course there is no such thing as a free lunch and the use of expression trees comes at the expense of some performance.

BTW is the font size of the code snippets sufficiently readable or is it too tiny?

UPDATE: Added support for Convert expressions (implicit/explicit casting)

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Dec 4th, 2009 (Views: 399)
Categories: Coding

Swine Flu (H1N1) as seen under microscope

Swine Flu

Swine Flu as seen under microscope

Note 1: You should be able to spot a particular kind of animal on the above image.

Note 2: I apologize if my humor hurts your feelings.

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Nov 10th, 2009 (Views: 123)
Categories: Diary
Tags:

Индонезия Ден 0: Истанбул Летище

В момента седя в един много приатен бар-ресторант на летището в Истанбул, което се казва Greenport. Преди час кацнах и доста обиколях терминала в търсене на контакт за лаптопшс, но тц – няма. За щастие скитайки нагоре надолу в този лабиринт забелязах една бойна група от 20-тина човека насядали с лаптопи и след кратък шпионски анализ открих контактите скрити в храстите… Не се бъзикам просто има декоративни храсти и контатките са прикрити там (защото са доста а така не се набиват на очи). И така сега си седя и хрупам една здравословна салата, охлаждам се с Diet Coke (Cola Light) с много лед (нямат ли климатици тия на това летище!?) и се подкрепям с едно не особено добро еспресо за 6 часа висенете до следващия полет до Jakarta, Indonesia. Самият полет ще е бая здрав – 13 часа и 10 000км.

Второто съществено нещо за това заведение е че има една лепенка скрита по средата на менюто с информацията за безплатно WiFi. Паролата обаче не работеше и питах един човечец до мен дали при него работи. Горкияt от 3часа e седял и циклел без да знае за инфото и направо се изчерви от яд. Life sucks какт знаем. В крайна сметка взех новата парола от един барман и ето качих малко снимки от летището.

Станал съм в 4 сутринта. Сега е 9 вечерта. Следвачият полет в в 11:30 и каца 6 часа следобед на следващие ден. Голям път, голямо нещо.

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (1 votes, average: 5.00 out of 5)
Loading ... Loading ...
Comments
Published: Oct 8th, 2009 (Views: 35)
Categories: Diary
Tags:

Fullmoon Trance on Full Moon

Was listening to a couple of Fullmoon Trance from my collection when I noticed it’s full moon – a pretty one.

Full moon

Full moon

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (1 votes, average: 5.00 out of 5)
Loading ... Loading ...
Comments
Published: Sep 4th, 2009 (Views: 48)
Categories: Diary
Tags:

HowTo Disable the Unsigned Security Warnings on Windows Mobile

The security warnings when deploying unsigned applications from Visual Studio to a real Windows Mobile device can get very annoying. Thankfully they can be disabled with a hack and here is how.

Using the Remote Registry Editor supplied with Visual Studio and with the Windows Mobile SDK installed change the following key value from 0 to 1 (and vise-versa to reset the change)

HKEY_LOCAL_MACHINE\Security\Policies\Policies\0000101a = 1

That’s it.

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Aug 15th, 2009 (Views: 194)
Categories: Coding, Technology

Ads Show in YouTube Videos

I just saw for the first time an advert in a YouTube video. Notice the “Ads by Google“. The video in question is http://www.youtube.com/watch?v=sekLEG8xsOs .

youtube-ads

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Aug 7th, 2009 (Views: 17)
Categories: Technology

Twitter Gmail Gadget

Just stumbled upon this awesome Twitter Gadget for Gmail. It not only adds a status update widget on the side but also a full interface to twitter as part of Gmail. Really cool and the interface is much nicer than the Twitter web page IMHO. Screenshot below. The Gadget can be found at http://twittergadget.appspot.com

To install:

1.   In Settings –> Labs enable “Add any gadget by URL” from the list.

2.   In Settings –> Gadgets –> Add https://twittergadget.appspot.com/gadget-gmail.xml .

You could also enable “Navbar drag and drop” so you can move the gadget up and down if you want.

Twitter Gmail Widget

Twitter Gmail Widget

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Jul 18th, 2009 (Views: 991)
Categories: Coding, Technology
Tags: ,

msysGit Tip: Files Constantly Reported as Modified Fix

I copied my Mono mcs Git working copy from Linux to Windows for use with MSysGit only to find out that even after git reset –hard almost all files were being reported as modified by git status. It turns out it has to do with the file permissions (executable bit I think) and the inability of msysgit to apply them on Windows.

$ git diff class/Accessibility/makefile.build
diff --git a/class/Accessibility/makefile.build b/class/Accessibility/makefile
old mode 100755
new mode 100644

The fix is to make git ignore some file mode stuff via:

git config core.fileMode false

Another useful setting on Windows is:

git config core.autocrlf true
  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Jul 18th, 2009 (Views: 248)
Categories: Coding
Tags: ,

Moving Out Fun

It was an exhausting three days moving out experience. Unfortunately unlike the Bachelors degree the Taught Masters one lasts a calendar year but the contracts of the student accommodation companies are only for an academic year. So I was lucky and found a room practically next door and had all the great fun of carrying all my belongings to the third floor. Two days of moving things, one day of unhuman back pain and cleaning and sorting out the old house and new room. The best part is when I went for a deserved coffee break in Planet Coffee on Newland Avenue and as I reached the bar got asked “The usual?” (which is Double Espresso a.k.a. “coffee” in most countries, Cake, Diet Coke). Don’t I feel like James Bond now?

  • Twitter
  • Facebook
  • FriendFeed
  • StumbleUpon
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Tumblr
  • PDF
  • Print
  • email
Rating: (No Ratings Yet)
Loading ... Loading ...
Comments
Published: Jul 17th, 2009 (Views: 22)
Categories: Diary
Tags:
This website uses a Hackadelic PlugIn, Hackadelic SEO Table Of Contents 1.7.3.