Last time, I hacked up some rudimentary support for F# and Fluent NHibernate. It really looked ugly. I looked into what I could do to make it not look as sucky.
First off, having to write a full lambda for each mapping was annoying. F# quotations don't have to be lambdas, unlike C#'s expressions. So, instead of having to write, say, "fun x -> x.Foo", we can write "x.Foo", assuming there's a local variable x with the right type. The ClassMap subclass now expects these types of quotations than full lambdas.
Next, I experimented with using type extensions to overload functions like Id and Map, however I found out that F#, at least currently, does not add in type extensions for overload resolution. So I ended up having a new subclass of ClassMap<T>, 'T ClassMapQ. I used the Q suffix consistently to denote "quotations". I added type extensions for most of the other mapping types so that quotations could be used.
As to the question of having to tag on " |> ignore " to each mapping, I decided to write an extension propery for IMappingPart called Done, which is simply unit. Finally, the problem of lazy loading I took care of by setting "use_proxy_validator" to false, as mentioned here. The end result is that this mapping code:
type StoreMap() = inherit ClassMap<Store>() do base.Not.LazyLoad() base.Id ~@@ <@ fun x -> x.Id @> |> ignore base.Map ~@@ <@ fun x -> x.Name @> |> ignore (base.HasManyX <@ fun x -> upcast x.Staff @>) .LazyLoad() .Inverse().Cascade.All() |> ignore (base.HasManyToManyX <@ fun x -> upcast x.Products @>) .Cascade.All() .WithTableName("StoreProduct") |> ignore
Is now:
type StoreMap() as m = inherit ClassMapQ<Store>() do let x = m.DefaultX (m.IdQ <@ x.Id @>).Done (m.MapQ <@ x.Name @>).Done (m.HasManyQ <@ seq x.Staff @>) .LazyLoad() .Inverse().Cascade.All() .Done (m.HasManyToManyQ <@ seq x.Products @>) .LazyLoad() .Cascade.All() .WithTableName("StoreProduct") .Done
This is pretty enough that I'm satisfied with how well F# interops. Most of the things I figured out here will apply to other .NET OO APIs, not just this one.
I am hoping that VS2010 Beta 1 will ship soon, as F# is getting some interesting upgrades then. With that, it should be easier to extend the support to other parts of NHibernate, such as querying, and perhaps integrate in NHibernate.Linq.
Remember Me