【问题标题】:Asp.net Core dependency injection in filters without [ServiceFilter] or [TypeFilter]没有 [ServiceFilter] 或 [TypeFilter] 的过滤器中的 Asp.net Core 依赖注入
【发布时间】:2018-11-27 23:28:51
【问题描述】:

我需要通过依赖注入向操作过滤器注入一些服务。我熟悉 [ServiceFilter][TypeFilter] 方法,但它有点丑陋、混乱和不清楚。

有没有办法以正常方式设置过滤器?不使用[ServiceFilter][TypeFilter] 包装我正在使用的过滤器?

例如我想要的:

[SomeFilterWithDI]
[AnotherFilterWithDI("some value")]
public IActionResult Index()
{
    return View("Index");
}

代替:

[ServiceFilter(typeof(SomeFilterWithDI))]
[TypeFilter(typeof(AnotherFilterWithDI), Arguments = new string[] { "some value" })]
public IActionResult Index()
{
    return View("Index");
}

看起来很不一样,这种方法对我来说似乎不合适。

【问题讨论】:

  • 您的过滤器使用 DI 吗?还有你所说的“正常方式”是什么意思?
  • @Shyju 是的,它确实使用 DI。 “正常方式” - 我的意思是没有 [ServiceFilter] 和 [TypeFilter] 包装我正在使用的过滤器。
  • 如果您的文件管理器中有 DI,这就是使用它的方法。我认为这是“正常方式”
  • 没有其他办法了。 DI/IoC 容器不是黑魔法。就其本质而言,必须使用已知参数来实例化属性(必须在编译时知道参数 - 这是 CIL/语言限制),这意味着只有常量。当然,您可以在 OnActionXxx 方法中访问context.HttpContext.RequestServices.GetRequiredService<IMyService>();,但这也不是很干净,当然,它不再称为依赖注入
  • 您可以为您的 first 示例实现IFilterFactory(不带参数)。

标签: c# asp.net-core dependency-injection asp.net-core-mvc asp.net-core-2.1


【解决方案1】:

对于[SomeFilterWithDI],您可以参考@Kirk larkin 的评论。

对于[AnotherFilterWithDI("some value")],您可以尝试从TypeFilterAttribute 传递Arguments

  • ParameterTypeFilter 定义接受参数。

    public class ParameterTypeFilter: TypeFilterAttribute
    {
    
        public ParameterTypeFilter(string para1, string para2):base(typeof(ParameterActionFilter))
        {
            Arguments = new object[] { para1, para2 };
        }
    }
    
  • ParameterActionFilter 接受传入的参数。

        public class ParameterActionFilter : IActionFilter
    {
        private readonly ILogger _logger;
        private readonly string _para1;
        private readonly string _para2;
    
        public ParameterActionFilter(ILoggerFactory loggerFactory, string para1, string para2)
        {
            _logger = loggerFactory.CreateLogger<ParameterTypeFilter>();
            _para1 = para1;
            _para2 = para2;
        }
    
        public void OnActionExecuting(ActionExecutingContext context)
        {
            _logger.LogInformation($"Parameter One is {_para1}");
            // perform some business logic work
    
        }
    
        public void OnActionExecuted(ActionExecutedContext context)
        {
            // perform some business logic work
            _logger.LogInformation($"Parameter Two is {_para2}");
        }
    }
    

    正如Arguments 的描述,ILoggerFactory loggerFactorydependency injection container 解析。 para1para2ParameterTypeFilter 解析。

        //
    // Summary:
    //     Gets or sets the non-service arguments to pass to the Microsoft.AspNetCore.Mvc.TypeFilterAttribute.ImplementationType
    //     constructor.
    //
    // Remarks:
    //     Service arguments are found in the dependency injection container i.e. this filter
    //     supports constructor injection in addition to passing the given Microsoft.AspNetCore.Mvc.TypeFilterAttribute.Arguments.
    public object[] Arguments { get; set; }
    
  • 用途

    [ParameterTypeFilter("T1","T2")]
    public ActionResult Parameter()
    {
        return Ok("Test");
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-16
    • 2019-02-22
    • 1970-01-01
    • 2017-01-08
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多