Go to the documentation of this file.00001 using System;
00002 using System.Web;
00003 using System.Web.Mvc;
00004 using System.Web.Routing;
00005 using N2.Engine;
00006 using System.Linq.Expressions;
00007
00008 namespace N2.Web.Mvc
00009 {
00013 [Service]
00014 public class ServiceLocatingControllerFactory : DefaultControllerFactory
00015 {
00016 private IEngine engine;
00017
00022 public ServiceLocatingControllerFactory(IEngine engine)
00023 {
00024 if (engine == null) throw new ArgumentNullException("engine");
00025 this.engine = engine;
00026 }
00027
00028 public override IController CreateController(RequestContext requestContext, string controllerName)
00029 {
00030
00031 EnsureDataToken(ContentRoute.ContentItemKey, requestContext.RouteData);
00032 EnsureDataToken(ContentRoute.ContentPageKey, requestContext.RouteData);
00033 if(!requestContext.RouteData.DataTokens.ContainsKey(ContentRoute.ContentEngineKey))
00034 requestContext.RouteData.DataTokens[ContentRoute.ContentEngineKey] = engine;
00035 return base.CreateController(requestContext, controllerName);
00036 }
00037
00038 private void EnsureDataToken(string key, System.Web.Routing.RouteData routeData)
00039 {
00040 if (!routeData.DataTokens.ContainsKey(key) && routeData.Values.ContainsKey(key))
00041 {
00042 int id = Convert.ToInt32(routeData.Values[key]);
00043 routeData.DataTokens[key] = engine.Persister.Get(id);
00044 }
00045 }
00046
00047 protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
00048 {
00049 if (controllerType == null)
00050 {
00051 if (NotFoundControllerSelector != null)
00052 {
00053 var pair = NotFoundControllerSelector(requestContext);
00054 controllerType = pair.ControllerType;
00055 foreach (var kvp in pair.RotueValues)
00056 requestContext.RouteData.Values[kvp.Key] = kvp.Value;
00057 }
00058
00059 if(controllerType == null)
00060 throw new HttpException(404, string.Format("The controller for path '{0}' could not be found or it does not implement IController.", requestContext.HttpContext.Request.Path));
00061 }
00062
00063 return (IController)engine.Resolve(controllerType);
00064 }
00065
00066
00067 public override void ReleaseController(IController controller)
00068 {
00069 var disposable = controller as IDisposable;
00070
00071 if (disposable != null)
00072 {
00073 disposable.Dispose();
00074 }
00075
00076 engine.Release(controller);
00077 }
00078
00079 class Pair
00080 {
00081 public Type ControllerType { get; set; }
00082 public RouteValueDictionary RotueValues { get; set; }
00083 }
00084
00086 private Func<RequestContext, Pair> NotFoundControllerSelector { get; set; }
00087
00088 public virtual void NotFound<T>(System.Linq.Expressions.Expression<Func<T, ActionResult>> expression) where T : IController
00089 {
00090 var method = (MethodCallExpression)expression.Body;
00091 var p = new Pair();
00092 p.ControllerType = method.Object.Type;
00093 p.RotueValues = new RouteValueDictionary { { "action", method.Method.Name } };
00094 NotFoundControllerSelector = (r) => p;
00095 }
00096 }
00097 }