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

时间:2017-04-23 05:19:45

标签: dependency-injection asp.net-core asp.net-core-mvc simple-injector

考虑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();
    }
}

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

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

是否有一些技巧可以让Simple Injector处理我的动作过滤器?我记得在旧的Simple Injector化身中曾经存在某种“过滤器提供者”的概念,允许这样做。

1 个答案:

答案 0 :(得分:9)

目前,ASP.NET Core MVC的Simple Injector集成包中没有任何内容可以简化处理过滤器属性的过程。我们仍然hoping微软将为框架添加简化以支持非构造者(自微软承诺make integration as smooth as it can be),但这似乎是lost cause

有一些解决方案。正如您所做的那样,一种方法是交叉布线。但是你越多,你越是将简单注入器中的控制权移出,你就越失去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);
}

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

container.Register<TestActionFilter>();

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

这适用于全局过滤器。对于控制器或操作范围的过滤器,请查看passive attributes