views:

162

answers:

1

I have implemented a service which uses a DAOFactory and a NHibernate Helper for the sessions and transactions. The following code is very much simplified:

public interface IService
{
    IList<Disease> getDiseases();
}

public class Service : IService
{
    private INHibernateHelper NHibernateHelper;
    private IDAOFactory DAOFactory;

    public Service(INHibernateHelper NHibernateHelper, IDAOFactory DAOFactory)
    {
        this.NHibernateHelper = NHibernateHelper;
        this.DAOFactory = DAOFactory;
    }

    public IList<Disease> getDiseases()
    {
        return DAOFactory.getDiseaseDAO().FindAll();
    }
}

public class NHibernateHelper : INHibernateHelper
{
    private static ISessionFactory sessionFactory;

    /// <summary>
    /// SessionFactory is static because it is expensive to create and is therefore at application scope.
    /// The property exists to provide 'instantiate on first use' behaviour.
    /// </summary>
    private static ISessionFactory SessionFactory
    {
        get
        {
            if (sessionFactory == null)
            {
                try
                {
                    sessionFactory = new Configuration().Configure().AddAssembly("Bla").BuildSessionFactory();
                }
                catch (Exception e)
                {
                    throw new Exception("NHibernate initialization failed.", e);
                }
            }
            return sessionFactory;
        }
    }

    public static ISession GetCurrentSession()
    {
        if (!CurrentSessionContext.HasBind(SessionFactory))
        {
            CurrentSessionContext.Bind(SessionFactory.OpenSession());
        }
        return SessionFactory.GetCurrentSession();
    }

    public static void DisposeSession()
    {
        var session = GetCurrentSession();
        session.Close();
        session.Dispose();
    }

    public static void BeginTransaction()
    {
        GetCurrentSession().BeginTransaction();
    }

    public static void CommitTransaction()
    {
        var session = GetCurrentSession();
        if (session.Transaction.IsActive)
            session.Transaction.Commit();
    }

    public static void RollbackTransaction()
    {
        var session = GetCurrentSession();
        if (session.Transaction.IsActive)
            session.Transaction.Rollback();
    }
}

At the end of the day I just want to expose the IService to ASP.NET MVC/Console application/Winform. I can already use the Service in a console application but would like to improve it first. I guess the first improvement would be to inject the interfaces INHibernateHelper and IDAOFactory via castle. But I think the problem is that the NHibernateHelper might cause problems in a asp.net context where NHibernateHelper should run according to the 'Nhibernate session per request' pattern. One question I have is whether this pattern is determined by the nhibernate config section (setting current_session_context_class = web) or can i control this via castle somehow?

I hope this makes sense. The final aim is just to expose THE IService.

Thanks.

Christian

A: 

You have two choices..

1) Host it in WCF. This allows you access from any source you want.

2) Abstract away everything that's specific to how the code is being used. In our system for instance we use our own Unit Of Work implementation which is stored differently based on where the code is running. A small example would be storing something using the WCF call context vs. the current thread.

ShaneC
I seem to be able to use PerWebRequest with Castle so far.
csetzkorn
Can you use just Castle to configure everything for option 2?
csetzkorn