Skip to content

Instantly share code, notes, and snippets.

@JeffreyZhao
Created August 20, 2009 03:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeffreyZhao/170798 to your computer and use it in GitHub Desktop.
Save JeffreyZhao/170798 to your computer and use it in GitHub Desktop.
AreaControllerFactory
public class AreaControllerFactory : IControllerFactory
{
private Dictionary<string, string> m_areaPartMapping = new Dictionary<string, string>();
private ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();
private Dictionary<string, Type> m_controllerTypes = new Dictionary<string, Type>();
public string NamespaceBase { get; private set; }
public AreaControllerFactory(string namespaceBase)
: this(namespaceBase, null)
{ }
public AreaControllerFactory(string namespaceBase, IDictionary<string, string> areaPartMapping)
{
this.NamespaceBase = namespaceBase.EndsWith(".") ? namespaceBase : namespaceBase + ".";
if (areaPartMapping != null)
{
foreach (var pair in areaPartMapping)
{
this.m_areaPartMapping.Add(pair.Key.ToLowerInvariant(), pair.Value);
}
}
}
public IController CreateController(RequestContext requestContext, string controllerName)
{
Type controllerType;
object area;
if (requestContext.RouteData.Values.TryGetValue("area", out area))
{
controllerType = this.GetControllerType(area.ToString(), controllerName);
}
else
{
controllerType = this.GetControllerType(null, controllerName);
}
if (controllerType == null)
{
throw new HttpException(404,
String.Format(
"Controller of path {0} not found.",
requestContext.HttpContext.Request.Path));
}
try
{
return (IController)Activator.CreateInstance(controllerType);
}
catch (Exception ex)
{
string message = String.Format("Error creating controller {0}" + controllerType);
throw new InvalidOperationException(message, ex);
}
}
private string GetNamespacePart(string area)
{
if (String.IsNullOrEmpty(area)) return "";
string part;
if (this.m_areaPartMapping.TryGetValue(area.ToLowerInvariant(), out part))
{
return part;
}
return area;
}
private Type GetControllerType(string area, string controllerName)
{
string part = this.GetNamespacePart(area);
string typeName = String.IsNullOrEmpty(part) ?
this.NamespaceBase + controllerName.ToLowerInvariant() + "Controller" :
this.NamespaceBase + part + "." + controllerName.ToLowerInvariant() + "Controller";
Type type;
this.m_rwLock.EnterReadLock();
try
{
if (this.m_controllerTypes.TryGetValue(typeName, out type))
{
return type;
}
}
finally
{
this.m_rwLock.ExitReadLock();
}
type = Type.GetType(typeName, false, true);
if (type != null)
{
this.m_rwLock.EnterWriteLock();
try
{
this.m_controllerTypes[typeName] = type;
}
finally
{
this.m_rwLock.ExitWriteLock();
}
}
return type;
}
public void ReleaseController(IController controller)
{
IDisposable disposable = controller as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment