首先要做两件事。
这个使用的项目基于Orchard 1.6,已知它与autofac 2.6.xxx兼容。我们目前不想经历可能冗长的升级到Autofac 3.0的过程,因此我们无法使用.AsActionFilter()选项。
另一个选项是将过滤器(扩展ActionFilterAttribute)设置为我们的基本控制器上的一个属性(所有其他的继承btw)。问题是过滤器本身有两个依赖关系:
我找不到的是将这些注入到班级头部的实际属性中的方法。有没有人知道通过注册期间Autofac的某些功能的[属性]行本身来实现这一目标的方法?
ActionFilterAttribute:
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]
任何人都有任何想法实现这一目标?
答案 0 :(得分:1)
您不能(轻松地)将属性中的运行时值注入。 这就是属性在C#中的工作方式 - 您只能传递某些类型的常量值。您可以阅读更多相关信息here。
为了在Orchard中实现所需的功能,您需要将代码分成两个部分:
FilterProvider
继承并实施IActionFilter
它的工作方式是将属性放在某个操作上,然后使用操作过滤器检查该属性的存在(使用filterContext.ActionDescriptor.GetCustomAttributes(...)
)。如果存在属性,请执行您的操作。
在Orchard核心中有很多这种技术的例子。检查例如。 ThemedAttribute
和ThemeFilter
操作过滤器类。