关于依赖关系注入:是否可以从ASP.NET Core项目中的Simple Injector注入IAsyncActionFilter?

Possible to inject into IAsyncActionFilter from Simple Injector in ASP.NET Core project?

在具有依赖性的ASP.NET Core MVC项目中考虑一个简单的动作过滤器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TestActionFilter : IAsyncActionFilter {
    private readonly IMyDependency _dep;

    public class TestActionFilter(IMyDependency dep)
    {
        _dep = dep;
    }

    public async Task OnActionExecutionAsync(ActionExecutingContext context,
                                             ActionExecutionDelegate next)
    {
        // do things with _dep...
        await next();
    }
}

我已经在Simple Injector中注册了IMyDependency并在其他地方工作。我也希望Simple Injector也可以处理动作过滤器。

如果我为同一类型添加IServiceCollection注册,它确实会注入到动作过滤器中。我不希望有两个绑定,但我试图避开框架容器,而只坚持使用简单注入器。

是否有一些技巧可以使简单注入器处理我的动作过滤器?我记得在较旧的简单注入器版本中曾经有某种"过滤器提供程序"概念允许这样做。


此刻,用于ASP.NET Core MVC的Simple Injector集成包中没有任何东西可以简化过滤器属性的使用。我们仍然希望Microsoft可以在框架中添加简化的格式以支持不符合标准的人(因为Microsoft承诺要使集成尽可能平滑),但这似乎是一个失败的原因。

有一些解决方案。就像您已经做过的那样,一种方法是交叉布线。但是跨线越多,您将控制权从Simple Injector中移出的越多,您失去的功能也越多,Simple Injector所提供的验证能力也就越大。当所有对象图都是单例时,这通常不会有太大问题,但这是一个不同的讨论。

另一个选择是在内置配置系统中创建一个代理过滤器,该代理过滤器委托给实际过滤器从简单注入器解决。这样的代理可以定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
public sealed class SimpleInjectiorAsyncActionFilterProxy<TAsyncActionFilter>
    : IAsyncActionFilter
    where TAsyncActionFilter : class, IAsyncActionFilter {
    private readonly Container container;
    public SimpleInjectiorAsyncActionFilterProxy(Container container) {
        this.container = container;
    }

    public Task OnActionExecutionAsync(
        ActionExecutingContext c, ActionExecutionDelegate n) =>
        container.GetInstance<TAsyncActionFilter>().OnActionExecutionAsync(c, n);
}

这是使用此代理连接过滤器的方式:

1
2
3
4
5
6
7
container.Register<TestActionFilter>();

services.AddMvc(options =>
{
    options.Filters.Add(
        new SimpleInjectiorAsyncActionFilterProxy<TestActionFilter>(container));
});

这对于全局过滤器非常有用。对于控制器或动作范围的过滤器,请看一下被动属性。