2

先从两件事说起。

  1. 我正在尝试实现一个动作过滤器,该过滤器记录动作何时开始以及何时结束
  2. 我很清楚 Autofac 3.0 中的 .AsActionFilter() 方法但是......

这里使用的项目基于 Orchard 1.6,已知它与 autofac 2.6.xxx 兼容。我们现在不想经历一个可能很长的升级到 Autofac 3.0 的过程,所以 .AsActionFilter() 选项对我们不可用。

另一个选项是将过滤器(扩展 ActionFilterAttribute)设置为我们的基本控制器上的一个属性(所有其他控制器都从它继承)。问题是过滤器本身有两个依赖项:

  1. 我们自己的服务,包含有关上下文的信息
  2. ILoggingService 的实现

我找不到一种将这些注入到类头的实际属性中的方法。有谁知道在注册期间通过 Autofac 的某些功能的 [Attribute] 行本身来实现此目的的方法?

动作过滤器属性:

public class GRMSActionLoggingFilter : ActionFilterAttribute {
    private readonly IGRMSCoreServices _grmsCoreServices;
    private readonly ILoggingService _loggingService;

    public GRMSActionLoggingFilter(IGRMSCoreServices grmsCoreServices, ILoggingService loggingService) {
        _grmsCoreServices = grmsCoreServices;
        _loggingService = loggingService;
    }

    public GRMSActionLoggingFilter() { }

    public override void OnActionExecuting(ActionExecutingContext actionContext) {...}
    public override void OnActionExecuted(ActionExecutedContext actionContext) {...}
}

将属性分配给基本控制器:

// This currently compiles but will fail during run time as the IGRMSCoreSerivces and ILoggingService will both be null. Need to property inject these services somehow. 
[GRMSActionLoggingFilter]

任何人有任何想法来实现这一目标?

4

1 回答 1

1

您不能(轻松)将运行时值注入属性。这就是属性在 C# 中的工作方式——您只能传递某些类型的常量值。你可以在这里阅读更多关于它的信息。

为了在 Orchard 中实现所需的功能,您需要将代码拆分为两个组件:

  • 您在操作中添加的标记属性类
  • 继承自FilterProvider并实现的动作过滤器类IActionFilter

它的工作方式是您将属性放在某个操作上,然后使用操作过滤器检查该属性的存在(使用filterContext.ActionDescriptor.GetCustomAttributes(...))。如果存在属性,请执行您的操作。

Orchard core 中有很多这种技术的例子。检查例如。和动作过滤器类ThemedAttributeThemeFilter

于 2013-05-08T13:55:51.153 回答