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

ASP.NET WebApi中基于Unity实现OWIN中间件的请求级依赖注入

解决ASP.NET WebApi(非DotNetCore)中Unity按请求实例化OWIN中间件的构造函数参数问题

嘿,我刚好踩过非Core ASP.NET WebApi + Unity + OWIN中间件的这个坑,给你理清楚问题根源和解决办法:

问题根源

你写的CustomMiddleware构造函数是完全符合OWIN中间件标准的——它需要接收OwinMiddleware next参数来串联管道,但Unity默认没办法直接处理OWIN管道传递的Func<Task>类型的next委托,因为你的构造函数期望的是OwinMiddleware实例,这就直接导致了编译错误。

正确的解决思路

我们需要把OWIN的Func<Task>委托包装成一个合法的OwinMiddleware子类实例,让Unity能把它作为参数注入到你的中间件构造函数里。具体步骤如下:

1. 编写OWIN委托包装类

这个类负责把OWIN管道的next委托转换成OwinMiddleware实例,适配你的构造函数要求:

public class OwinMiddlewareWrapper : OwinMiddleware
{
    private readonly Func<Task> _nextFunc;

    public OwinMiddlewareWrapper(Func<Task> nextFunc) : base(null)
    {
        _nextFunc = nextFunc;
    }

    public override Task Invoke(IOwinContext context)
    {
        return _nextFunc();
    }
}

2. 编写Unity中间件注册扩展方法

用这个方法替代默认的Use<CustomMiddleware>(),让Unity按请求实例化中间件并注入正确的next参数:

public static class UnityOwinExtensions
{
    public static IAppBuilder UseUnityMiddleware<T>(this IAppBuilder app, IUnityContainer container) 
        where T : OwinMiddleware
    {
        return app.Use(async (context, next) =>
        {
            // 用Unity解析中间件,同时传入包装后的next实例
            var middleware = container.Resolve<T>(
                new ParameterOverride("next", new OwinMiddlewareWrapper(next))
            );
            await middleware.Invoke(context);
        });
    }
}

3. 在Startup中注册中间件

在Configuration方法里,用自定义扩展方法注册你的中间件,同时确保Unity容器已注册其他需要注入的依赖:

public void Configuration(IAppBuilder app)
{
    // 初始化Unity容器并注册业务依赖
    var container = new UnityContainer();
    container.RegisterType<IMyService, MyService>(); // 示例:注册你的业务服务

    // 用Unity按请求实例化中间件
    app.UseUnityMiddleware<CustomMiddleware>(container);

    // 常规WebApi配置
    var config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();
    app.UseWebApi(config);
}

4. 保持你的CustomMiddleware不变

你原来的中间件代码是正确的,甚至可以直接添加其他Unity需要注入的依赖:

public class CustomMiddleware : OwinMiddleware 
{ 
    // 可以添加其他Unity注入的依赖,比如业务服务
    private readonly IMyService _myService;

    public CustomMiddleware(OwinMiddleware next, IMyService myService) : base(next) 
    { 
        _myService = myService;
    } 

    public override async Task Invoke(IOwinContext context)
    {
        // 执行你的中间件逻辑,比如用_myService处理请求
        await Next.Invoke(context); // 调用管道中的下一个中间件
    }
}

不推荐的替代方案(仅供参考)

如果你不想写包装类,也可以直接修改中间件构造函数接收Func<Task>,但这会破坏OWIN中间件的标准结构,后续扩展和维护会受限:

public class CustomMiddleware : OwinMiddleware 
{ 
    private readonly Func<Task> _next;

    public CustomMiddleware(Func<Task> next) : base(null) 
    { 
        _next = next;
    } 

    public override async Task Invoke(IOwinContext context)
    {
        // 你的中间件逻辑
        await _next();
    }
}

内容的提问来源于stack exchange,提问作者James Law

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:29:02