可以从ASP.NET Core项目中的Simple Injector注入IAsyncActionFilter吗?

ken*_*ada 2 dependency-injection simple-injector asp.net-core-mvc asp.net-core

考虑ASP.NET Core MVC项目中的一个简单的动作过滤器,它采用依赖:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经在IMyDependencySimple Injector注册并在其他地方工作.我希望Simple Injector也能处理动作过滤器.

如果我IServiceCollection为同一类型添加注册,它会被注入动作过滤器.我不想要两个绑定,我试图避免框架容器,只是坚持使用Simple Injector.

是否有一些技巧可以使Simple Injector处理我的动作过滤器?我记得在旧的Simple Injector化身中曾经存在过某种"过滤器提供者"的概念.

Ste*_*ven 9

目前,ASP.NET Core MVC的Simple Injector集成包中没有任何内容可以简化处理过滤器属性的过程.我们仍然希望微软能够为框架添加简化以支持非构造者(因为微软承诺尽可能顺利进行集成),但这似乎是一个失败的原因.

有一些解决方案.正如您所做的那样,一种方法是交叉布线.但是你越多,你越是将简单注入器中的控制权移出,你就越失去Simple Injector提供的验证能力.当所有对象图都是单例时,这通常不会成为一个问题,但这是一个不同的讨论.

另一种选择是在内置配置系统中创建代理过滤器,该过滤器委托给从Simple Injector解析的实际过滤器.这种代理可以定义如下:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

container.Register<TestActionFilter>();

services.AddMvc(options =>
{
    options.Filters.Add(
        new SimpleInjectiorAsyncActionFilterProxy<TestActionFilter>(container));
});
Run Code Online (Sandbox Code Playgroud)

这适用于全局过滤器.在控制器或动作范围过滤器方面,请查看被动属性.