Peter's Gekko

Sponsors

The Lounge

Wicked Cool Jobs

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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 !

 


Posted Fri, Mar 7 2008 9:40 AM by pvanooijen

[Advertisement]

Comments

Mogens Heller Grabe wrote re: Setting and retrieving the database connectionstring in nHibernate
on Fri, Mar 7 2008 5:10 AM

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.

Daily Bits - March 7, 2008 | Alvin Ashcraft's Daily Geek Bits wrote Daily Bits - March 7, 2008 | Alvin Ashcraft's Daily Geek Bits
on Fri, Mar 7 2008 9:25 AM

Pingback from  Daily Bits - March 7, 2008 | Alvin Ashcraft's Daily Geek Bits

Setting and retrieving the database connectionstring in nHibernate - Peter's Gekko wrote Setting and retrieving the database connectionstring in nHibernate - Peter's Gekko
on Fri, Mar 7 2008 3:25 PM

Pingback from  Setting and retrieving the database connectionstring in nHibernate - Peter's Gekko

Tobin Harris wrote re: Setting and retrieving the database connectionstring in nHibernate
on Fri, Mar 7 2008 10:38 PM

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!

pvanooijen wrote re: Setting and retrieving the database connectionstring in nHibernate
on Sat, Mar 8 2008 11:29 AM

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 ?

http://scrum.codebetter.com/blogs/peter.van.ooijen/archive/2008/03/07/setting-and-retrieving-the-database-connectionstring-in-nhibernate.aspx wrote http://scrum.codebetter.com/blogs/peter.van.ooijen/archive/2008/03/07/setting-and-retrieving-the-database-connectionstring-in-nhibernate.aspx
on Mon, Mar 24 2008 3:57 AM
Peter's Gekko wrote Wrapping up nHibernate
on Wed, Mar 26 2008 7:02 AM

In a relative short span of time nHibernate has become a major member of my toolbox. It has become the

http://monkeys.codebetter.com/blogs/peter.van.ooijen/archive/2008/03/07/setting-and-retrieving-the-database-connectionstring-in-nhibernate.aspx wrote http://monkeys.codebetter.com/blogs/peter.van.ooijen/archive/2008/03/07/setting-and-retrieving-the-database-connectionstring-in-nhibernate.aspx
on Wed, Apr 9 2008 11:53 AM
Alan Yost wrote re: Setting and retrieving the database connectionstring in nHibernate
on Fri, Jan 9 2009 9:09 AM

Great tip - using reflection works a treat.

Thanks

Technical Related Notes » Blog Archive » links for 2008-03-08 wrote Technical Related Notes » Blog Archive » links for 2008-03-08
on Sun, Jan 11 2009 7:59 PM

Pingback from  Technical Related Notes  » Blog Archive   » links for 2008-03-08

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us