DB specific conventions in Fluent NHibernate

275 Views Asked by At

I have a set of Fluent NHibernate conventions most of which are database independent. However, there are a couple which are DBMS dependent such one for string properties:

Public Sub Apply(ByVal instance As IPropertyInstance) Implements IConvention(Of IPropertyInspector, IPropertyInstance).Apply
    instance.CustomSqlType("VARCHAR2(50 BYTE)")
End Sub

Really I just use a convention like this one for DB generation (i.e. objects first development). This works all well and good for Oracle, but I then want do unit testing using an in-memory SQLite DB and obviously this convention wont work, as SQLite has no VARCHAR2 type.

Does anyone have any good advice or references on how they configure Fluent NHibernate in such circumstances.

At the moment I'm thinking along the lines of having a generic set of conventions that are database independent and then having the dependent ones in a sub directory/namespace. I would then have some kind of configuration that allows me to specify a custom ITypeSource component which would pick up all the generic conventions as well as the ones associated to the specific DBMS e.g. SqlConventionTypeSource, OracleConventionTypeSource...

Kind regards, Ryan.

1

There are 1 best solutions below

4
On

You generally set up your conventions (as well as the rest of your fluent configuration) in the executable.

That means you'll have a different fluent configuration in your GUI, your unit tests, and anything else that happens to be consuming your ISession/ISessionFactory based services.

It sounds to me like you've hard-coded your configuration and are now trying to figure out how to get that "configurator" to act differently depending on some information about the environment.

A much simpler way would be to create your configuration at the top level and provide it as a dependency to whatever needs it. That way you're not shoehorned into the same code path from different environments.

Whatever it is that depends on NHibernate, set it up to accept an ISession or ISessionFactory as a constructor argument or property setter. Then you won't have this issue. You can even mock it for tests that don't actually need to query the data store.

Of course you can still set up whatever class creates the FNH config to be configurable in itself, and use conditional statements in the config lines. But usually a FNH config is so few lines of code to begin with, it hardly seems worth it. Just create totally separate configurations for SQL Server, Oracle, SQLite, etc. That way you won't have to constantly maintain it every time you make a minor change.