Fluent NHibernate is a tool that lets you easily write NHibernate mappings.
I downloaded the code and was awe-struck. It's really tidy and full of nicely implemented ideas.
####In-Memory Repository One of them was the in-memory repository class. It uses LINQ for queries, and keeps an in-memory cache of objects. Check out this test-cases that demonstrates it's use.
InMemoryRepository repository = new InMemoryRepository();
repository.Save(new Case { Name = "Jeremy", Number = 10 });
repository.Save(new Case { Name = "Darth Vader", Number = 5 });
repository.Save(new Case { Name = "Darth Maul", Number = 6 });
repository.Save(new Case { Name = "Luke", Number = 12 });
repository.Save(new Case { Name = "Han Solo", Number = 6 });
repository.Save(new Case { Name = "Eric", Number = 5 });
repository.Save(new Case { Name = "Corwin", Number = 4 });
repository.FindBy<Case>(c => c.Name == "Corwin").Name.ShouldEqual("Corwin");
repository.FindBy<Case>(c => c.Number == 10).Name.ShouldEqual("Jeremy");
repository.FindBy<Case>(c => c.Number == 6 && c.Name == "Han Solo").Name.ShouldEqual("Han Solo");
Gotta love the Star-Wars geekery :)
This kind of repository is useful for testing domain logic without hitting the DB. This in turns makes domain model testing very fast. For example, the 263 in-memory test take only 4 seconds to complete. I could live with that.
####LINQ for NHIbernate Repository Jeremy has also created a real repository that implements the same interface as the in-memory one. That means it also uses LINQ. And that means it uses LINQ for NHIbernate - hurrah !
Here's the real repository in action:
ISession session = _source.CreateSession();
session.SaveOrUpdate(new Record { Name = "Jeremy", Age = 34 });
session.SaveOrUpdate(new Record { Name = "Jeremy", Age = 35 });
session.SaveOrUpdate(new Record { Name = "Jessica", Age = 29 });
session.SaveOrUpdate(new Record { Name = "Natalie", Age = 25 });
session.SaveOrUpdate(new Record { Name = "Hank", Age = 29 });
session.SaveOrUpdate(new Record { Name = "Darrell", Age = 34 });
session.SaveOrUpdate(new Record { Name = "Bill", Age = 34 });
session.SaveOrUpdate(new Record { Name = "Tim", Age = 35 });
session.SaveOrUpdate(new Record { Name = "Greg", Age = 36 });
Repository repository = new Repository(_source.CreateSession());
Record record = repository.FindBy<Record>(r => r.Age == 34 && r.Name == "Jeremy");
record.Name.ShouldEqual("Jeremy");
record.Age.ShouldEqual(34);
There are currently only 9 integration tests that actually use NHIbernate and hit a DB. Pretty cool considering the nature of the project.
####Lots to Learn There's a lot to learn from this project.
One thing is that not hitting a database for 90% of your tests is a GREAT THING.
In this project, the 9 tests that hit the database take a whopping 7 seconds to run on my machine! That's 0.8 seconds per test on average. The in-memory tests take only 0.015 seconds each on average.
####Favourite Mapping Technique? I have a feeling that Fluent-NHibernate will become my favourite way of writing mappings for NHIbernate. And, I soon hope that it will soon be my favourite way of NOT writing mappings for NHibernate :) Of course, they'll need to get their Auto Mapping working for that, but I believe they'll do it within the next 2-3 months.
I now looking forward to browsing more of the code and trying out the tool...