kooboo cms可替换Controller扩展性
为进一步增加kooboo cms的可扩展性,要实现现有controller的可替换机制,群里看到阿不说“写一个ControllerFactory就可以解决”的字样。
一开始没有理解其中的原由,也完全不清楚该怎么实现这一扩展,简单思考后猜想mvc应该是通过工厂方法来取得controller的实例,然后可以实现一个自己的Factory来替换即可。遂打开mvc3源码看个究竟,果然找到了IControllerFactory这个借口,也看到DefaultControllerFactory,这印证了我的猜想,happy!(汗!js写多了c#变得陌生)。
以下是具体的扩展思路:
1.继承IControllerFactory,实现其接口方法,或是继承DefaultControllerFactory,根据需要进行适当的重写。
推介只用后者,简单方便,提供一个存储自定义Controller类型的容器,并提供一个注册类型的API。
public class TestControllerFactory : DefaultControllerFactory { static Dictionary<string, Type> CustomizeControllers; static TestControllerFactory() { CustomizeControllers = new Dictionary<string, Type>(); } public static void RegisterCustomizeController(Type t) { CustomizeControllers[t.Name] = t; } protected internal override Type GetControllerType(RequestContext requestContext, string controllerName) { if (CustomizeControllers.ContainsKey(controllerName)) { return CustomizeControllers[controllerName]; } else { return base.GetControllerType(requestContext, controllerName); } } }
2.在扩展的dll里面利用PreApplicationStartMethod实现注册,这样的好处是零配置,只要将dll拷贝到bin目录即可。
[assembly: System.Web.PreApplicationStartMethod(typeof(Test.AssemblyInitializer), "Initialize")] namespace Test { public static class AssemblyInitializer { public static void Initialize() { TestControllerFactory.RegisterCustomizeController(typeof(TestExtentController)); } } public class TestExtentController : Controller { } }
3.万事具备了。。。等等!这时候MVC还不知道TestControllerFactory的存在呀,没错,我们还需要在Global中注册TestControllerFactory实例给MVC,替换掉默认的DefaultControllerFactory。
protected void Application_Start() { ControllerBuilder.Current.SetControllerFactory(new TestControllerFactory()); // others RegisterRoutes(RouteTable.Routes); }
思路完毕,代码没有经过验证也没有运行起来过,纯思路而已。
浏览器没那么聪明!