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 !