如何向UnityContainer注册多接口实现类?MVC5自动注册IRunOnEachRequest类
嘿,我来帮你搞定Unity.Mvc里自动注册IRunOnEachRequest实现类的问题,顺便聊聊你提到的RegisterType<IRunAfter...的疑问!
一、自动注册所有IRunOnEachRequest实现类
要通过反射批量注册,你可以在UnityConfig.cs的RegisterTypes方法里这么写,逻辑很清晰:
public static void RegisterTypes(IUnityContainer container) { // 1. 扫描当前程序集(或所有加载的程序集),找出所有实现IRunOnEachRequest的非抽象类 var targetTypes = typeof(IRunOnEachRequest).Assembly.GetTypes() .Where(t => typeof(IRunOnEachRequest).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface); // 2. 批量注册每个实现类,绑定到IRunOnEachRequest接口 foreach (var type in targetTypes) { // 重点:用PerRequestLifetimeManager,确保每个HTTP请求生成一个实例 container.RegisterType(typeof(IRunOnEachRequest), type, new PerRequestLifetimeManager()); // 如果你后续需要通过具体类名直接获取实例,再加这行: // container.RegisterType(type, new PerRequestLifetimeManager()); } // --- 下面处理你提到的IRunAfter...相关注册 --- // 假设你说的是类似IRunAfterRequest这类同生命周期的接口,核心是选对生命周期管理器: // container.RegisterType<IRunAfterSomething, YourImplementation>(new PerRequestLifetimeManager()); }
关键细节说明:
PerRequestLifetimeManager:这是Unity.Mvc专门为MVC请求设计的生命周期,刚好匹配IRunOnEachRequest的语义——每个请求创建一个实例,请求结束后自动释放。- 反射范围调整:如果你的实现类分散在多个程序集里,把
typeof(IRunOnEachRequest).Assembly改成AppDomain.CurrentDomain.GetAssemblies(),但记得过滤掉系统程序集(比如加.Where(asm => !asm.FullName.StartsWith("System.")))。
二、关于
container.RegisterType<IRunAfter...的疑问解答 我猜你纠结的点大概率是生命周期的选择,给你整理几种常见场景:
- 如果是和
IRunOnEachRequest一样的「每个请求执行一次」:用PerRequestLifetimeManager; - 如果是全局单例(整个应用生命周期只实例化一次):用
ContainerControlledLifetimeManager; - 如果每次获取都要新实例:用
TransientLifetimeManager(这是Unity默认的生命周期); - 如果是每个子容器一个实例:用
HierarchicalLifetimeManager(适合嵌套容器场景)。
三、额外补充:让IRunOnEachRequest实例自动执行
注册完之后,你可能需要让这些类在每个请求时自动跑起来,这里给你一个简单的实现思路:
写一个全局Action过滤器,从容器里拿到所有IRunOnEachRequest实例并执行:
public class RunOnEachRequestFilter : ActionFilterAttribute { private readonly IEnumerable<IRunOnEachRequest> _handlers; // 构造函数注入所有IRunOnEachRequest实现类 public RunOnEachRequestFilter(IEnumerable<IRunOnEachRequest> handlers) { _handlers = handlers; } public override void OnActionExecuting(ActionExecutingContext filterContext) { foreach (var handler in _handlers) { handler.Execute(); // 假设你的IRunOnEachRequest定义了Execute方法 } base.OnActionExecuting(filterContext); } }
然后在Global.asax的Application_Start里全局注册这个过滤器:
GlobalFilters.Filters.Add(DependencyResolver.Current.GetService<RunOnEachRequestFilter>());
这样每次请求都会自动触发所有IRunOnEachRequest实现类的逻辑啦!
内容的提问来源于stack exchange,提问作者Junior
相关产品推荐
相关产品推荐

