如何用StructureMap实现ASP.NET控制器与ApiController的AOP方法拦截
我来帮你梳理下基于StructureMap动态拦截实现ASP.NET控制器和ApiController方法拦截的完整方案,结合你给出的拦截器代码做完善和补充:
实现ASP.NET控制器/ApiController方法的AOP拦截
1. 完善拦截器类
你已经写了基础的AuthorisationInterceptor,这里补全完整代码并加上实用注释,方便你后续扩展权限验证、日志等功能:
using StructureMap.Interception; using System; using System.Reflection; public class AuthorisationInterceptor : ISyncInterceptionBehavior { public IMethodInvocationResult Intercept(ISyncMethodInvocation methodInvocation) { // 获取被拦截方法所属的控制器类型 var controllerType = methodInvocation.Method.DeclaringType; // 获取被拦截的方法名称 var methodName = methodInvocation.Method.Name; // 获取方法上标记的所有特性 var methodAttributes = methodInvocation.Method.GetCustomAttributes(true); // 获取控制器类上标记的所有特性 var controllerAttributes = controllerType.GetCustomAttributes(true); // 这里可以根据业务需求扩展逻辑,比如: // - 校验方法/控制器上的权限特性 // - 记录方法调用日志 // - 参数合法性校验 Console.WriteLine($"已拦截到控制器[{controllerType.Name}]的方法[{methodName}]调用"); // 执行原始方法,不中断业务流程 return methodInvocation.Proceed(); } // 设置拦截器执行顺序:值越小,拦截器越先执行 public int Order => 1; }
2. 配置StructureMap容器,启用控制器拦截
接下来需要在StructureMap的注册配置中,指定对所有控制器类型应用拦截器:
using StructureMap; using StructureMap.Interception; using System.Web.Mvc; using System.Web.Http; public class ControllerRegistry : Registry { public ControllerRegistry() { // 扫描并注册当前程序集中的所有控制器 Scan(scanner => { scanner.TheCallingAssembly(); scanner.AddAllTypesOf<Controller>(); // 注册MVC控制器 scanner.AddAllTypesOf<ApiController>(); // 注册Web API控制器 }); // 配置拦截规则:对所有继承自Controller或ApiController的类型应用拦截器 Policies.InterceptWith<AuthorisationInterceptor>(type => typeof(Controller).IsAssignableFrom(type) || typeof(ApiController).IsAssignableFrom(type)); } }
3. 在ASP.NET项目中集成StructureMap
根据你的项目类型(MVC或Web API),完成容器的初始化和依赖注入替换:
对于ASP.NET MVC项目
在Global.asax.cs的Application_Start方法中添加初始化逻辑:
protected void Application_Start() { // 常规MVC初始化(路由、过滤器等) AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); // 初始化StructureMap容器 ObjectFactory.Initialize(config => config.AddRegistry<ControllerRegistry>()); // 替换MVC默认的依赖解析器 DependencyResolver.SetResolver(new StructureMapDependencyResolver(ObjectFactory.Container)); }
对于ASP.NET Web API项目
同样在Global.asax.cs的Application_Start中配置:
protected void Application_Start() { // 常规Web API初始化 GlobalConfiguration.Configure(WebApiConfig.Register); // 初始化StructureMap容器 var container = new Container(new ControllerRegistry()); // 替换Web API默认的依赖解析器 GlobalConfiguration.Configuration.DependencyResolver = new StructureMapWebApiDependencyResolver(container); }
额外提示
- 如果需要拦截异步方法,请实现
IAsyncInterceptionBehavior接口,而非ISyncInterceptionBehavior,它提供了处理异步调用的专属方法。 - 你可以通过
methodInvocation.Arguments获取方法的传入参数,用于参数校验或日志埋点。 - 如果需要中断方法执行(比如权限校验不通过),可以返回自定义的
IMethodInvocationResult,例如methodInvocation.CreateExceptionResult(new UnauthorizedAccessException())。
内容的提问来源于stack exchange,提问作者user9314395
相关产品推荐
相关产品推荐

