2
votes

I am trying to make a few endpoints use NHibernate persistence, after using in-memory persistence for development. I am using the latest Nuget packages.

Right off the bat I get the following exceptions. It mentioned Topshelf upon which NServiceBus.Host is based, but I have no idea why.

Please note: I don't get any errors at all using in-memory persistence.

Exception thrown: 'System.InvalidOperationException' in NServiceBus.NHibernate.dll Exception thrown: 'System.InvalidOperationException' in NServiceBus.Host.exe Exception thrown: 'Magnum.StateMachine.StateMachineException' in NServiceBus.Host.exe Additional information: Exception occurred in Topshelf.Internal.ServiceController`1[[NServiceBus.Hosting.Windows.WindowsHost, NServiceBus.Host, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c]] during state Initial while handling OnStart

Exception thrown: 'Magnum.StateMachine.StateMachineException' in NServiceBus.Host.exe Additional information: Exception occurred in Topshelf.Internal.ServiceController`1[[NServiceBus.Hosting.Windows.WindowsHost, NServiceBus.Host, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c]] during state Initial while handling OnStart

Exception thrown: 'System.InvalidOperationException' in mscorlib.dll An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll Additional information: No NHibernate properties found in your config file (E:\Projects.........\MyEndpoint.dll.config).

To run NServiceBus with NHibernate you need to at least specify the database connectionstring. Here is an example of what is required:

<!-- other optional settings examples -->
<add key="NServiceBus/Persistence/NHibernate/connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<add key="NServiceBus/Persistence/NHibernate/connection.driver_class"

value="NHibernate.Driver.Sql2008ClientDriver"/>

<!-- Optional overrides per persister -->
<add name="NServiceBus/Persistence/NHibernate/Timeout" connectionString="Data Source=.\SQLEXPRESS;Initial

Catalog=timeout;Integrated Security=True" />

The documentation doesn't say these settings are mandatory in the app.config of every endpoint. I want to configure this exclusively in code. Is that even possible?

This is my NH configuration, for which I have created an empty SqlServer 2014 database called "nservicebus":

    config.EnableInstallers();

    var nhConfig = new Configuration
    {
        Properties =
        {
            ["dialect"] = "NHibernate.Dialect.MsSql2012Dialect",
            ["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider",
            ["connection.driver_class"] = "NHibernate.Driver.Sql2012ClientDriver"
        }
    };

    config.UsePersistence<NHibernatePersistence>().UseConfiguration( nhConfig );
....

What am I missing? The documentation makes it sound simple, but it's not.

EDIT

What made this work was to do it this way:

        config.EnableInstallers();

        //OLD, didn't work
        //var nhConfig = new Configuration
        //{
        //    Properties =
        //    {
        //        ["dialect"] = "NHibernate.Dialect.MsSql2012Dialect",
        //        ["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider",
        //        ["connection.driver_class"] = "NHibernate.Driver.Sql2012ClientDriver"
        //    }
        //};

        var nhConfiguration = new Configuration();
        nhConfiguration.SetProperty( NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider" );
        nhConfiguration.SetProperty( NHibernate.Cfg.Environment.ConnectionDriver, "NHibernate.Driver.Sql2008ClientDriver" );
        nhConfiguration.SetProperty( NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSql2008Dialect" );
        nhConfiguration.SetProperty( NHibernate.Cfg.Environment.ConnectionStringName, "NServiceBus/Persistence" );

        config.UsePersistence<NHibernatePersistence>().UseConfiguration( nhConfiguration );

The MsSql2008Dialect also works with Sql 2012, 2014.

What remains in the app.config is the connection string, which I need for Entity Framework anyway.

But, as @DavidBoike mentions below, you can also take that out of the app.config and configure it programatically.

1

1 Answers

2
votes

You can configure the connection string pretty easily in code:

busConfiguration.UsePersistence<NHibernatePersistence>()
    .ConnectionString("your-connection-string-here");

You do need to include the NServiceBus.Persistence namespace for the extension method to be available.

You are right that the NHibernate Persistence documentation page does not cover simply setting the connection string very well. I've opened a GitHub issue on the docs repository to track this.