考虑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化身中曾经存在某种“过滤器提供者”的概念,允许这样做。
答案 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。