我需要创建一个实现IActionModelConvention
和IFilterFactory
的自定义操作过滤器。
我使用IActionModelConvention
同时设置多条路由,并且我使用IFilterFactory
注入一些我需要使用的服务。
问题是,在Apply()
的{{1}}方法之前调用了IActionModelConvention
的{{1}}方法,我需要注入的服务将在CreateInstance()
中可用。
我的问题是在调用IFilterFactory
方法之前如何注入服务?而且我还更喜欢使用Apply()
来注入服务,因为这不会迫使我用Apply()
或IFilterFactory
属性来包装实际属性。
这是我的代码:
[ServiceFilter]
答案 0 :(得分:1)
您的IActionModelConvention
实现在启动时将只运行一次。 Apply
将为每个操作调用一次。为了在ISomeService
函数内部使用Apply
,可以将其作为构造函数参数传递。您的Contains2RoutesAttribute
类不必是IFilterFactory
的属性或实现,因为您已经在注释中确认它不参与filter pipeline。这是一个代码示例,在这里我还重命名了该类以更好地表示其正在执行的操作(它不再是属性):
public class Contains2RoutesConvention : IActionModelConvention
{
private readonly ISomeService someService;
public Contains2RoutesConvention(ISomeService someService)
{
this.someService = someService;
}
public void Apply(ActionModel actionModel)
{
someService.DoSomething();
...
}
}
您可以使用以下方法在Startup.ConfigureServices
中注册此约定:
services.AddMvc(options =>
{
options.Conventions.Add(new Contains2RoutesConvention(new SomeService()));
});
在这里变得更加有趣。您不能在convention中使用依赖项注入,因此在此示例中,我在构造SomeService
时内联创建了Contains2RoutesConvention
的实例。如果您希望该实例成为可在应用程序中其他位置使用的单例,则可以在ConfigureServices
中进行如下操作:
var someService = new SomeService();
services.AddMvc(options =>
{
options.Conventions.Add(new Contains2RoutesConvention(someService));
});
services.AddSingleton<ISomeService>(someService);
当然,这取决于SomeService
是否具有自己的依赖关系,但是如果存在依赖关系,则它们将无法从DI容器中解决,因为它在管道中为时过早。