Home

Castle Stronghold

Understanding Scopes

Any database related ActiveRecord operations ultimately delegates the task to NHibernate and all NHibernate operation demands an ISession instance.

When ActiveRecord is about to delegate something to NHibernate it checks if there is a ISession instance available and if not, one is created and disposed as soon as the operation is completed.

A SessionScope is a way to encapsulate and extend the life of a NHibernate's ISession instance. Once one is active, when ActiveRecord checks for an ISession instance, the scope is found and from that point on it is in charge of providing the session.

It is adamant that you know the basics of what is the purpose of NHibernate ISession, the Flush operation and supported Flush behaviors. Please take a moment to read NHibernate documentation.

ISessionFactoryHolder

The ISessionFactoryHolder interface implementation holds and manages one or more session factories (one per database configured). Any ActiveRecord operation invokes CreateSession and ReleaseSession, for example:


protected internal static Array FindAll(Type targetType, Order[] orders, params ICriterion[] criterias)
{
    ISession session = holder.CreateSession(targetType);
    
    try
    {
        // implementation omitted for clarity
    }
    catch(ValidationException)
    {
        throw;
    }
    catch(Exception ex)
    {
        throw new ActiveRecordException("Could not perform FindAll for " + targetType.Name, ex);
    }
    finally
    {
        holder.ReleaseSession(session);
    }
}

The holder implementation always checks for a registered scope.


[MethodImpl(MethodImplOptions.Synchronized)]
public ISession CreateSession(Type type)
{
    if (threadScopeInfo.HasInitializedScope)
    {
        return CreateScopeSession(type);
    }

    ISessionFactory sessionFactory = GetSessionFactory(type);

    ISession session = OpenSession(sessionFactory);

    System.Diagnostics.Debug.Assert( session != null );

    return session;
}

ISessionScope

The ISessionScope interface defines the contract for possible scope implementations. All scopes must have a fixed type that defines its semantic.

We have three builtin supported scopes:

Read only Scopes

A NHibernate ISession manages the changes made to entities and Flush them in some situations. If your process performs lots of read, and is not supposed to write, or when you decide when a write should be performed, then you can create a SessionScope that does not perform Flush.


using(new SessionScope(FlushAction.Never))
{
    // lots of operations db related here
}

For these cases performance will be greatly improved. However it is up to you to manage the Flush:


using(new SessionScope(FlushAction.Never))
{
    // lots of operations

    // Everything is OK, flush the changes
    SessionScope.Current.Flush();
}
Google
Search WWW Search castleproject.org