3

In ServiceStack application, I have Funq configured to inject a session per request like this:

container.Register<NHibernate.ISessionFactory>(sessionFactoryForDB1);
container.Register<NHibernate.ISession>(c => c.Resolve<NHibernate.ISessionFactory>()
  .OpenSession())
  .ReusedWithin(Funq.ReuseScope.Request);

My service looks like this, and it works just fine:

public class MyNhAwareService : Service
{
   public ISession Session { get; set; }

   public object Any(DoSomething request)
   {
   ...
   }
}

Now, the problem comes in when I want to add a second NHibernate database into the mix with its own session factory:

container.Register<NHibernate.ISessionFactory>(sessionFactoryForDB1);
container.Register<NHibernate.ISession>(c => c.Resolve<NHibernate.ISessionFactory>()
   .OpenSession())
   .ReusedWithin(Funq.ReuseScope.Request);
// add a different session factory 
container.Register<NHibernate.ISessionFactory>(sessionFactoryForDB2);

I've been experimenting with a variety of ways Funq can be used, and I thought I had found the way forward when I discovered the 'RegisterNamed()" method, but that still doesn't help, as I can't use anything except TryResolve() from within my service.

This seems like it should be possible, but I'm beating my head against the wall trying to work it out...Any advice would be greatly appreciated.

David Montgomery
  • 1,618
  • 15
  • 28

1 Answers1

5

You have a couple ways of going about this.

Option 1: Unique Interfaces

This option is to create a distinct interface for each NHibernate database so that they can be uniquely resolved by Funq.

For example:

interface FactoryA : NHibernate.ISessionFactory
{
} 

interface FactoryB : NHibernate.ISessionFactory
{
} 

You could then proceed as you are now. The same applies for the session. See here for a little more detail about the process:

How to register multiple IDbConnectionFactory instances using Funq in ServiceStack.net

Option 2: Named Instance

This option I am less familiar with, but you can name your instances using Funq:

container.Register<NHibernate.ISessionFactory>("FactoryA",sessionFactoryForDB1);

And then in your service, resolve it thusly:

ServiceStackHost.Instance.Container.ResolveNamed<NHibernate.ISessionFactory>("FactoryA");

This option uses Service Location, which I personally find less attractive.

Community
  • 1
  • 1
Jeff Mitchell
  • 1,459
  • 1
  • 17
  • 33
  • Your Option #1 seems like the superior method, and doesn't suffer from magic-string-itis. And thanks for the "ServiceStackHost.Instance.Container" pointer -- that was the piece I was missing for grabbing the Func container from within a service! – David Montgomery May 19 '14 at 19:06