Real Web Developers

Service collection Fluent Nhibernate

Author
Scott Rickman
Last updated
2026-09-07

NHiberateOptions.cs


namespace RealWebDevelopers;
    
public class NHibernateOptions
{
    public required string ConnectionString { get; set; }
    public required string SessionContext { get; set; }
}
    

Extensions.cs

namespace RealWebDevelopers;

using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using Microsoft.Extensions.Options;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
using Models;

public static class Extensions
{
    public static IServiceCollection AddNHibernate(this IServiceCollection services)
    {
        services.AddSingleton<ISessionFactory>(implementationFactory =>
        {
            var options = implementationFactory.GetRequiredService<IOptions<NHibernateOptions>>().Value;
            return Fluently.Configure()
                .Database(MySQLConfiguration.Standard
                    .ConnectionString(options.ConnectionString)
                    .ShowSql())
                .Mappings(mappings => mappings.AutoMappings.Add(AutoMap.AssemblyOf<Program>()
                    .Where(where => where.Namespace!.Equals("CrmPolicyMessageSubscriber.Models", StringComparison.OrdinalIgnoreCase))
                    .Override<Customer>(populateMap =>
                    {
                        populateMap.Id(memberExpression => memberExpression.Reference).Not.Nullable().Length(31);
                        populateMap.Map(memberExpression => memberExpression.FirstName).Not.Nullable().Length(127);
                        populateMap.Map(memberExpression => memberExpression.LastName).Not.Nullable().Length(127);
                        populateMap.Map(memberExpression => memberExpression.EmailAddress).Not.Nullable().Length(127);
                        populateMap.Map(memberExpression => memberExpression.PhoneNumber).Nullable().Length(31);
                        populateMap.Map(memberExpression => memberExpression.AddressLine1).Not.Nullable().Length(127);
                        populateMap.Map(memberExpression => memberExpression.AddressLine2).Not.Nullable().Length(127);
                        // ...
                    })))
                .ExposeConfiguration(config =>
                {
                    config.Properties.Add("current_session_context", options.SessionContext);
                    new SchemaUpdate(config).Execute(true, true);
                })
                .BuildSessionFactory();
        });
        services.AddScoped<ISession>(implementationFactory => { return implementationFactory.GetRequiredService<ISessionFactory>().OpenSession(); });
        return services;
    }
}
    

appsettings.json

{
    "Logging": {
        ...
    },
  "NHibernateOptions": {
    "ConnectionString": "Server=localhost;Port=3311;Database=crmdb;Uid=crmapi;Password=1234567890",
    "SessionContext": "web"
  }
}
    

Program.cs

namespace RealWebDevelopers;

using Microsoft.Extensions.Options;

public class Program
{
    public static void Main(string[] args)
    {
        // boiler plate web application
        builder.Services.AddOptions<NHibernateOptions>().Bind(builder.Configuration.GetSection("NHibernateOptions"));
        builder.Services.AddNHibernate();

        // etc.
    }
}