如何为Umbraco的RenderMvcController实现Simple Injector子集注册并保留后台控制器?
解决方案:用Simple Injector注册自定义RenderMvcController且保留Umbraco后台控制器
针对你遇到的问题——既要用Simple Injector管理Umbraco的RenderMvcController子类,又不想接管Umbraco后台控制器,这里有一套可靠的实现方案:
1. 禁用全局MVC控制器自动注册
首先,不要使用Simple Injector默认的RegisterMvcControllers方法(它会扫描并注册所有控制器,包括Umbraco内部的),而是手动注册你自己的RenderMvcController实现。
这样可以避免Simple Injector尝试解析Umbraco后台的控制器(这些控制器依赖Umbraco内部服务,Simple Injector无法提供,从而导致报错)。
示例代码:
var container = new Container(); container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); // 批量注册你项目中所有自定义的RenderMvcController子类 container.Register( typeof(RenderMvcController), Assembly.GetExecutingAssembly().GetTypes() .Where(t => typeof(RenderMvcController).IsAssignableFrom(t) && !t.IsAbstract), Lifestyle.Scoped); // 或者单个注册特定控制器 // container.Register<MyCustomRenderController>(Lifestyle.Scoped);
2. 实现混合控制器工厂
核心思路是:让Simple Injector只负责创建你的自定义RenderMvcController,其他所有控制器(包括Umbraco后台的)交给Umbraco原生的控制器工厂处理。
创建一个继承自Umbraco控制器工厂的自定义工厂:
public class HybridUmbracoControllerFactory : Umbraco.Web.Mvc.UmbracoControllerFactory { private readonly Container _container; public HybridUmbracoControllerFactory(Container container) { _container = container; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { // 判断是否是我们自定义的RenderMvcController子类 if (controllerType != null && typeof(RenderMvcController).IsAssignableFrom(controllerType) && !controllerType.Namespace.StartsWith("Umbraco.")) { // 用Simple Injector解析控制器 return _container.GetInstance(controllerType) as IController; } // 其他控制器交给Umbraco原生逻辑处理 return base.GetControllerInstance(requestContext, controllerType); } }
3. 替换控制器工厂并完成初始化
最后,把MVC的控制器工厂替换为我们的混合工厂,同时设置Simple Injector的依赖解析器:
// 设置Simple Injector为MVC的依赖解析器 DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); // 替换控制器工厂为混合工厂 ControllerBuilder.Current.SetControllerFactory(new HybridUmbracoControllerFactory(container)); // 验证容器配置(开发环境建议启用,生产环境可关闭) container.Verify();
为什么之前的尝试失败?
你提到显式注册后仍报错,大概率是因为Simple Injector的MVC集成默认会尝试解析所有控制器(包括Umbraco后台的),而这些控制器依赖Umbraco内部的未注册服务。通过上面的混合工厂,我们彻底隔离了Simple Injector的作用范围,只处理我们自己的控制器,完美避免了这个问题。
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

