You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:39:03