Setting and retrieving the database connectionstring in nHibernate

All the good work nHibernate is doing may sometimes look like magic but just like any "old-style" db programming it needs a plain old connectionstring to get to the database. There are many ways to pass this connectionstring. In a lot of examples it is a part of the configuration file where it is either a part of the app.config or the web.config or even a custom xml file which is explicitly loaded from code.

You can also completely configure nHibernate from code. This snippet does the essentials

static public void LoadConfiguration(string domainAssembly, string connectionString)

{

    dBconnectionString = connectionString;

    Configuration cfg = new Configuration();

    IDictionary props = new Hashtable();

    props.Add("hibernate.dialect", "NHibernate.Dialect.MsSql2000Dialect");

    props.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");

    props.Add("hibernate.connection.connection_string", connectionString);

    cfg.SetProperties(props);

    cfg.AddAssembly(domainAssembly);

    sessionFactory = cfg.BuildSessionFactory();

}

 

Note that the database dialect is hard coded. The bare essentials, the name of the assembly providing the domain objects and the connectionstring, are passed in.

So there are many way to specify the connectionstring. But what about the other way round? What if you want to know the connectionstring nHibernate is actually using? I’ve been Googling and browsing around on this and did find out I’m not the only one. I came up with a solution which works in some, but not all, scenarios. It is possible to read the connectionstring on an open session. Like this:

public static string ConnectionString

{

    get

    {

        ISession session = SessionFactory.OpenSession();

        string result;

        try

        {

            result = session.Connection.ConnectionString;

        }

        catch (ADOException nhaex)

        {

            result = nhaex.Message;

        }

        return result;

    }

}

 

But what if the session cannot be opened; most likely because the connectionstring is invalid? In such a case it would be nice to know that value. But here you will get a message telling you it cannot open the connection without containing any information what connection it cannot open.

I have looked everywhere but could not find any readable trace of the desired string at all. As a workaround I now store the connectionstring when loading the configuration. But I’m not that satisfied with that as it looks redundant and is not idiot proof. So if anybody has an idea; you’re more than welcome.

Update:

I’ve looked everywhere, but not with reflector or inside the nHibernate sourcecode. In a comment Mogens Heller Grabe provided the info that the connectionstring is a non public member of the SessionFactory. Using reflection you can retrieve the value of any private member, provided you know it’s name. Hereby I include his code, for the sake of clarity I’ve renamed the variables

public static string ConnectionString

{

    get

    {

        Type typeOfConnectionProvider = typeof(NHibernate.Connection.DriverConnectionProvider);

        PropertyInfo ConnectionStringPropertyInfo = typeOfConnectionProvider.GetProperty("ConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);

        string connectionString = (string)ConnectionStringPropertyInfo.GetValue(sessionFactory.ConnectionProvider, null);

        return connectionString;

    }

}

 

Which works well; also without opening a connection. Imho it would be quite usefull to surface this property and make the getter public. I could even do it myself as nHibernate is OS. But for now this is good enough for me. Thanks !

 

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.mookid.dk/oncode Mogens Heller Grabe

    If you know your IConnectionProvider is a NHibernate.Connection.DriverConnectionProvider you can do it like this:

    Type t = typeof (NHibernate.Connection.DriverConnectionProvider);
    PropertyInfo pi = t.GetProperty(“ConnectionString”, BindingFlags.Instance | BindingFlags.NonPublic);
    string connectionString = (string)pi.GetValue(sessionFactory.ConnectionProvider, null);

    The connection is accessible in the connection provider via a private property, so we need to use reflection to get the value.

  • http://www.tobinharris.com/blog Tobin Harris

    I can see why this would be handy (I’ve needed it myself!), but shouldn’t a connection string be considered a “secret”, and therefore erased from memory as soon as it’s served it’s purpose? It worries me a bit to think that there are connection strings hanging around in memory for the duration of the session!

  • http://codebetter.com/blogs/peter.van.ooijen/ pvanooijen

    You open a new sessions every time you invoke the OpenSession method of the sessionfactory. To open a new session the sessionfactory needs the connectionstring. You only have to provide that once when creating the SF, after that no further “secret” info is needed. Imho security reasons make no sense here. You can get to the database and read the connectionstring anyway. So why not expose the string anyway ?

  • Alan Yost

    Great tip – using reflection works a treat.

    Thanks

  • Dipen Lama

    Easy way to get connection string in nHibernate 2.1 is

    Configuration cfg = new Configuration()
    cfg.GetProperty(“connection.connection_string”);

  • Dipen

    This is the easy way to get connection string in nHibernate 2.

    NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();

    string connectionString = cfg.GetProperty(“connection.connection_string”);