Search code examples
c#nhibernatefluenttraversaldomain-model

NHibernate Traversal Question - Creating a Fluent Interface


I'm stumped with NHibernate and my Domain Model right now. I'm imagining a nice API in my head but I'm having a really hard time making it a reality. Here's an example of what I'm trying to accomplish:

Trip trip = new Trip("Austria2009");

foreach(User user in trip.People.Crew.IsApproved())
{
    reponse.write(user.Firstname);
}

// Or I could hack some of the stuff off above and make it look like this
foreach(User user in trip.People.Crew)
{
    reponse.write(user.Firstname);
}

// Or yet again pull all the people back and forget a specific role
foreach(User user in trip.People)
{
    reponse.write(user.Firstname);
}

So does that stuff in the Foreach loop making any lick of sense? :P I feel like I'm trying to create some kind of fluent interface with my classes. I'm using NHibernate for persistence so is something like this possible or do I just need to make things a LOT simpler?


Solution

  • Assuming that Trip is an IQueryable, a fluent interface could be written fairly easily with Linq queries and extension methods. NOTE: The following hypothetical code is not tested.

    public static class MyExtensions
    {
        public static IQueryable<Person> People(this IQueryable<Person> source)
        {
            return from person in source
                   select person;
        }
    
        public static IQueryable<Person> Crew(this IQueryable<Person>  source)
        {
            return from person in source
                   where person.type == crewMember
                   select person;
        }
        public static IQueryable<Person> IsApproved(this IQueryable<Person>  source)
        {
            return from person in source
                   where person.IsApproved == true
                   select person;
        }
    }
    

    ..etc. Notice the use of the "this" keyword in the parameter list of each method. This allows the method to be called by dotting any IQueryable source, as in:

    var crew = myPersons.Crew();
    var approvedCrew = myPersons.Crew().IsApproved();
    

    NOTE: I don't believe there is a way to eliminate the parentheses using this technique. To do that you would need to use properties, and C# does not support "Extension Properties", only "Extension Methods."

    More info here: http://en.wikipedia.org/wiki/Fluent_interface