Castle ActiveRecord and registering classes at runtime
I use the following trick for adding ActiveRecord classes after the fact for our in-house plug-in architecture. Thanks to whichever blogger/mailing list I picked this up from so long ago.
Scenario 1: Class(es) to load inherit from same base class as current running ActiveRecord classes
var holder = ActiveRecordMediator.GetSessionFactoryHolder();
ActiveRecordStarter.RegisterTypes(typeof(Employee), typeof(Customer)); //register your subclasses here
holder.RegisterSessionFactory(
holder.GetConfiguration(typeof(ActiveRecordBase)).BuildSessionFactory(), typeof(ActiveRecordBase)
);//reloads session factory without this types will not be registered. I believe this is actually a "feature" in Castle trunk. may be fixed now.
This is all you need to register extra classes that are accessing the same database as the application is using.
Scenario 2: Not only must the new types be registered but a new base class with its new configuration as well
InPlaceConfigurationSource source = new InPlaceConfigurationSource();
Dictionary<string, string> confdict = new Dictionary<string, string> // config. change this to suite your needs
{{"connection.driver_class", "NHibernate.Driver.SqlClientDriver"},
{"dialect" ,"NHibernate.Dialect.MsSql2000Dialect"},
{"connection.provider","NHibernate.Connection.DriverConnectionProvider"},
{"connection.connection_string","Data Source=localhost;Initial Catalog=intranet_devel;Integrated Security=SSPI"},
{"proxyfactory.factory_class","NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"}
};
source.Add(typeof(BaseCRMobj), confdict);
var holder = ActiveRecordMediator.GetSessionFactoryHolder();
var config = new Configuration();
foreach (var conf in source.GetConfiguration(typeof(BaseCRMobj)).Children) //turns ActiveRecord config Configuration could be skipped if you load Configuration object instead
{
config.Properties[conf.Name] = conf.Value;
}
holder.Register(typeof(BaseCRMobj), config); // loads the base type and its configuration into ActiveRecord
holder.RegisterSessionFactory(holder.GetConfiguration(typeof(BaseCRMobj)).BuildSessionFactory(), typeof(BaseCRMobj)); //reloads sessionfactory again note not using ActiveRecordBase now
After you have configured the base type for your ActiveRecord classes plus its connection string then call the register types method again:
var holder = ActiveRecordMediator.GetSessionFactoryHolder();
ActiveRecordStarter.RegisterTypes(typeof(Employee), typeof(Customer)); // register individual subclasses
holder.RegisterSessionFactory(holder.GetConfiguration(typeof(BaseCRMobj)).BuildSessionFactory(), typeof(BaseCRMobj)); //reloads instance of SessionFactory
Overall this works quite well even if its noisy . I’m able to dynamically load connections to 5 different databases and register a hundred or so classes total, all after the application has started. The real code has some DRY cleanup going on but this is more or less what I really use.