Skip to content

Instantly share code, notes, and snippets.

@randomcodenz
Created March 22, 2011 20:27
Show Gist options
  • Save randomcodenz/881975 to your computer and use it in GitHub Desktop.
Save randomcodenz/881975 to your computer and use it in GitHub Desktop.
using System;
using System.Web.Mvc;
using System.Web.Routing;
using GoFetchV2.Infrastructure;
namespace GoFetchV2.Web.Mvc
{
/// <summary>
/// Conventions are as follows:
/// 1. All controllers must be registered in the container
/// 2. All controllers will be resolved via the container
/// 3. If a controller type cannot be determined from the request or found in the container, use the default ConventionController
/// which will decide how to handle the request rather than having the factory throw a 404
/// </summary>
public class ConventionControllerFactory : DefaultControllerFactory
{
// ReSharper disable AccessToModifiedClosure
public override IController CreateController( RequestContext requestContext, string controllerName )
{
ControllerBase controllerBase = null;
Func<ControllerContext> contextFactory = () => controllerBase == null ? null : controllerBase.ControllerContext;
RequestScope.Begin( requestContext, contextFactory );
var container = RequestScope.Container;
var controller = container.TryGetInstance<IController>( controllerName.ToLowerInvariant() );
if (controller == null)
{
controller = container.GetInstance<ConventionController>();
}
controllerBase = controller as ControllerBase;
return controller;
}
// ReSharper restore AccessToModifiedClosure
public override void ReleaseController( IController controller )
{
RequestScope.End();
}
}
}
using System;
using System.Collections;
using System.Web.Mvc;
using System.Web.Routing;
using StructureMap;
namespace GoFetchV2.Infrastructure
{
public static class RequestScope
{
private static Func<IDictionary> _requestScopedStore;
private const string RequestScopedContainerKey = "RequestScopedContainer";
public static IContainer Container
{
get
{
return (IContainer)_requestScopedStore()[ RequestScopedContainerKey ];
}
private set
{
_requestScopedStore()[ RequestScopedContainerKey ] = value;
}
}
public static void Initialise( Func<IDictionary> requestScopedStore )
{
_requestScopedStore = requestScopedStore;
}
public static void Begin( RequestContext requestContext, Func<ControllerContext> controllerContext )
{
var requestContainer = ObjectFactory.Container.GetNestedContainer();
requestContainer.BeginRequestScope( requestContext, controllerContext );
Container = requestContainer;
}
public static void End()
{
var requestContainer = Container;
_requestScopedStore().Remove( RequestScopedContainerKey );
requestContainer.EndRequestScope();
requestContainer.Dispose();
}
}
}
using System;
using System.Web.Mvc;
using System.Web.Routing;
using GoFetchV2.Infrastructure.Container;
using StructureMap;
namespace GoFetchV2.Infrastructure
{
public static class RequestScopedContainer
{
public static void BeginRequestScope( this IContainer container, RequestContext requestContext, Func<ControllerContext> controllerContext )
{
container.BeginSessionScopeScope();
var requestScopeRegistry = new RequestScopeRegistry( requestContext, controllerContext );
container.Configure( config => config.AddRegistry( requestScopeRegistry ) );
}
public static void EndRequestScope( this IContainer container )
{
container.EndSessionScope();
}
}
}
using System.Data;
using NHibernate;
using StructureMap;
namespace GoFetchV2.Infrastructure
{
public static class SessionScopedContainer
{
public static void BeginSessionScopeScope( this IContainer container )
{
var session = BeginSession( container.GetInstance<ISessionFactory>() );
container.Configure( config => config.For<ISession>().Use( session ) );
}
public static void EndSessionScope( this IContainer container )
{
EndSession( container.GetInstance<ISession>() );
}
private static ISession BeginSession( ISessionFactory sessionFactory )
{
// All work in a session MUST be managed by a transaction so create a default transaction here
// Use ReadCommitted as that is the default transaction isolation level used normally by nhibernate as well as being
// recommended in a number of places. See http://www.bestguesstheory.com/2009/03/nhibernate-and-snapshot-isolation.html
var session = sessionFactory.OpenSession();
session.BeginTransaction( IsolationLevel.ReadCommitted );
return session;
}
private static void EndSession( ISession session )
{
if( session == null )
{
return;
}
if( session.Transaction.IsActive && !session.Transaction.WasRolledBack )
{
session.Transaction.Commit();
}
session.Dispose();
}
}
}
In Global.asax.cs ...
protected void Application_Start()
{
// ... bunch of other init stuff
RequestScope.Initialise( () => HttpContext.Current.Items );
// ... bunch of other init stuff
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment