Notice: The content in this post may be out of date, please refer to the Fluent Configuration page in the Fluent NHibernate Wiki for the latest version.

There’s been a grey area of how to actually configure your application to use Fluent NHibernate, and also how to configure some more complicated situations (such as mixing fluent and non-fluent mappings). After some thought I’ve committed a change that should make things clearer. What follows is a few examples of how this new API can be used.

I’m going to assume that you’ve got an application already set up, or you know how to structure a standard NHibernate application. If you don’t, I suggest you read up on that first.

All the examples that follow are tailored to directly replace your SessionFactory instantiation code.

Introducing the configuration API

You can now Fluently.Configure your application. The API is broken down into five main methods, three of which are required.

Fluently.Configure()
  .Database(/* your database settings */)
  .Mappings(/* your mappings */)
  .ExposeConfiguration(/* alter Configuration */) // optional
  .BuildSessionFactory();

You can combine these methods in various ways to setup your application.

  1. Fluently.Configure starts the configuration process
  2. Database is where you specify your database configuration
  3. Mappings is where you supply which mappings you’re using
  4. ExposeConfiguration is optional, but allows you to alter the raw Configuration object
  5. BuildSessionFactory is the final call, and it creates the NHibernate SessionFactory instance from your configuration.

Exclusively fluent

If you’re in the situation where your application is exclusively using fluent mappings, then this is the configuration for you.

var sessionFactory = Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory)
  .Mappings(m =>
    m.FluentMappings
      .AddFromAssemblyOf<YourEntity>())
  .BuildSessionFactory();

This setup uses the SQLite database configuration, but you can substitute that with your own; it then adds any fluent mappings from the assebly that contains YourEntity.

Automappings

If you’re using only auto mappings, then this config is for you.

var sessionFactory = Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory)
  .Mappings(m =>
    m.AutoMappings.Add(
      // your automapping setup here
      AutoPersistenceModel.MapEntitiesFromAssemblyOf<YourEntity>()
        .Where(type => type.Namspace.EndsWith("Entities"))))
  .BuildSessionFactory();

Replace the code inside AutoMappings.Add with your auto mapping configuration. You can see more about auto mappings in my automapping tag.

Mixed fluent mappings and auto mappings

If you’re using a combination of standard fluent mappings and auto mappings, then this example should show you how to get started.

var sessionFactory = Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory)
  .Mappings(m =>
  {
    m.FluentMappings
      .AddFromAssemblyOf<YourEntity>();

    m.AutoMappings.Add(
      // your automapping setup here
      AutoPersistenceModel.MapEntitiesFromAssemblyOf<YourEntity>()
        .Where(type => type.Namspace.EndsWith("Entities")));
  })
  .BuildSessionFactory();

You can see that this is a combination of the two previous examples, the Mappings method can accept multiple kinds of mappings.

HBM mappings

You’ve not yet got around to using Fluent NHibernate fully, but you are configuring your database with it; this configuration will let you configure your database and add your traditional hbm mappings.

var sessionFactory = Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory)
  .Mappings(m =>
    m.HbmMappings
      .AddFromAssemblyOf<YourEntity>())
  .BuildSessionFactory();

The HbmMappings property allows you to add HBM XML mappings in a few different ways, this example adds everything from an assembly which defines YourEntity; however, you can add from an assembly instance, or just add single types.

Mixed HBM and fluent mappings

You’re migrating your entities to Fluent NHibernate but haven’t quite got them all across yet – this is for you.

var sessionFactory = Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory)
  .Mappings(m =>
  {
    m.HbmMappings
      .AddFromAssemblyOf<YourEntity>();

    m.FluentMappings
      .AddFromAssemblyOf<YourEntity>();
  })
  .BuildSessionFactory();

The whole shebang: fluent, auto, and hbm mappings

You’re a crazy fool and map a bit of everything, then this is how you’d configure it.

var sessionFactory = Fluently.Configure()
  .Database(SQLiteConfiguration.Standard.InMemory)
  .Mappings(m =>
  {
    m.HbmMappings
      .AddFromAssemblyOf<YourEntity>();

    m.FluentMappings
      .AddFromAssemblyOf<YourEntity>();

    m.AutoMappings.Add(
      // your automapping setup here
      AutoPersistenceModel.MapEntitiesFromAssemblyOf<YourEntity>()
        .Where(type => type.Namspace.EndsWith("Entities")));
  })
  .BuildSessionFactory();

Exporting hbm.xml mappings

In the Mappings call, you can do the following:

.Mappings(m =>
{
  m.FluentMappings
    .AddFromAssemblyOf<YourEntity>()
    .ExportTo(@"C:\your\export\path");

  m.AutoMappings
    .Add(...)
    .ExportTo(@"C:\your\export\path");
})

That will export all of your fluent and automapped mappings in hbm.xml format to whatever location you specify.

Altering non-automapped conventions

If you want to override conventions that are used by your non-automapped classes, then you can use the AlterConventions method on FluentMappings.

.Mappings(m =>
  m.FluentMappings
    .AddFromAssemblyOf<YourEntity>()
    .AlterConventions(conventions =>
    {
      conventions.IsBaseType =
        type => type == typeof(BaseType);
    }))

Validation

If you forget to setup your database, or don’t add any mappings, instead of pulling out your hair over obscure NHibernate exceptions, the BuildSessionFactory method will throw a more helpful exception to try to point you in the right direction. It’ll tell you whether you’ve forgot to add any entities, or not setup your database.

That’s it for now, I hope this helps to make configuring your application a little clearer.

Tags:

Comments...

  1. James,

    As always your blog posts make your new changes really easy to work with. My project StructuredWeb that’s similar to Sh#rp architecture but IMO much easier to use and understand is about to be released so I’ll be adding more to the blogosphere about using FNH even if some of it is just rehashed in your earlier posts but I still think it will help people to see my mapping over the Northwind db since it’s moderately close to a real world application.

    By Chris Marisic2 Feb, 2009 @ 4:59 am

  2. Sorry I may be being a bit dense – how can I get access to the Configuration object for a FluentConfiguration for use with SchemaExport?

    By Harry M2 Feb, 2009 @ 11:26 am

  3. Harry: You can grab it from inside the ExposeConfiguration method.

    I do it something like this:

    Fluently.Configure()
      .Database(/* your database settings */)
      .Mappings(/* your mappings */)
      .ExposeConfiguration(BuildSchema)
      .BuildSessionFactory();
    

    Where BuildSchema is:

    private void BuildSchema(Configuration cfg)
    {
      new SchemaExport(cfg)
        .Create(false, true);
    }
    

    By James Gregory2 Feb, 2009 @ 11:32 am

  4. how do you do testing on TDD(like nunit) on
    connection is valid and really can pull some data?

    here’s my code below, It seems the connection is the problem, that’s
    why may test yield null objects.

    private ISessionFactory CreateSessionFactory()
    {
    return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2005
    .ConnectionString(c => c
    .Is(“Data Source=OSMDBFUNC;Initial
    Catalog=ManDatabase;Persist Security Info=True;User
    ID=sa;Password=s@”))
    .ShowSql())
    .Mappings(m => m
    .HbmMappings.AddFromAssemblyOf())
    .BuildSessionFactory();
    }

    How do i test this one, that the Session have a live and can pull some data on my database?

    Thanks,

    NoBody

    By No Body — 3 Mar, 2009 @ 5:26 am

  5. Ok, I am fine now.

    Is seems,

    this is not working:
    .Database(MsSqlConfiguration.MsSql2005
    .ConnectionString(c => c
    .Is(“Data Source=OSMDBFUNC;Initial
    Catalog=ManDatabase;Persist Security Info=True;User
    ID=sa;Password=s@”))

    and changed it to: now it working =)

    .Database(MsSqlConfiguration.MsSql2005
    .ConnectionString(c => c
    .Server(“osmdbfunc”)
    .Database(“ManDatabase”)
    .Username(“sa”)
    .Password(“s@”))

    FYI:
    - Case-Sensitive in play

    I still want the test fixture =).
    And whats the different on the above, am I missing something?

    thanks,
    No Body.

    By No Body — 3 Mar, 2009 @ 7:20 am

  6. Please use the mailing list for support, you’ll get a better response from there.

    As for your problem, why not just query an entity? It’ll blow up if it can’t reach the database.

    By James Gregory3 Mar, 2009 @ 9:42 am

  7. Sweet!

    Can I just say I’m really impressed so far with Fluent nHibernate docs… I appreciate the time you’ve put in on the wiki and here.

    By 5x1llz — 5 May, 2009 @ 12:40 pm

  8. where is SQLiteConfiguration declared/from?
    as in SQLiteConfiguration.Standard.InMemory

    By jay — 1 Jan, 2010 @ 4:06 pm

  9. jay: it’s declared in FluentNHibernate.Cfg.Db

    By James Gregory1 Jan, 2010 @ 10:28 am

  10. how to setup the following in the current RTM.

    model.Conventions.GetForeignKeyName = prop => prop.Name + “Id”;

    all i want to change Resource_Id to ResourceId.

    no sample.. nothing exists.

    By achu — 1 Jan, 2010 @ 7:08 pm

  11. The wiki is your friend, read it.

    Conventions, converting to new-style conventions,
    foreign-key conventions, and
    convention shortcuts.

    By James Gregory1 Jan, 2010 @ 10:14 am

Post a comment...