nhibernatecastle-windsorfacilitieswindsor-nhfacilitywindsor-facilities

Injecting Correct ISessionFactory Into IRepository Using Castle Windsor and NHibernate Facility


I have three SQL Server databases that a single application retrieves data from. I am using NHibernate to retrieve data from the different databases. I have things set up so that each database has its own repository and class mappings in its own assembly. In my castle.config file I have the database connections setup using the Castle NHibernate Facility:

<?xml version="1.0" encoding="utf-8" ?>
<castle>
  <facilities>
    <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.Windsor" />
    <facility id="nhibernate" isWeb="false" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
      <factory id="databaseone.factory" alias="databaseone">
        <settings>
            <!--Settings Here -->
        </settings>
        <assemblies>
           <assembly>DAL.DatabaseOne</assembly>
        </assemblies>
      </factory>
      <factory id="databasetwo.factory" alias="databasetwo">
        <settings>
          <!--Settings Here -->
        </settings>
        <assemblies>
          <assembly>DAL.DatabaseTwo</assembly>
        </assemblies>
      </factory>
      <factory id="databasethree.factory" alias="databasethree">
        <settings>
            <!--Settings Here -->
        </settings>
        <assemblies>
             <assembly>DAL.DatabaseThree</assembly>
        </assemblies>
      </factory>
    </facility>
  </facilities>
</castle>

All of my repositories have a constructor that take an ISessionFactory as the parameter:

public MyRepository<T> : IRepository<T>
{
   public MyRepository(ISessionFactory factory)
   {
        //Do stuff here
   }
 }

I have an installer class where I would like to define the various repositories:

//In install method of IWindsorInstaller
container.register(Component.For(typeof(IRepository<>)).ImplementedBy(typeof(MyRepository<>));

Using one database things work fine. When I add the second database to the mix, the same ISessionFactory is injected into all of the repositories. My question is what is the best way to handle this? I could manually specify which ISessionFactory should be injected into which Repository<> but I cannot seem to find documentation on this. The best way would be if I could say something like: For all class mappings in assembly DAL.DatabaseOne, always inject the ISessionFactory corresponding to databaseone.factory; and for all class mappings in assembly DAL.DatabaseTwo, always inject the ISessionFactory corresponding to databasetwo.factory.

Thoughts or suggestions?


Solution

  • This is explained in this post by Fabio Maulo toward the end under the heading 'Configuring your DAOs/Repository for multiple DB'.

    He maps the factory individually for each domain class but you could also use reflection on each of the domain assemblies in your case to register the appropriate factory.