我在这方面已经找到了一些问题,但他们倾向于指出我正在遵循的确切文档......但它仍然没有用。
我正在构建一个相当简单的ASP.NET MVC 4站点,计划是使用基于ActionFilterAttribute
的日志记录。我有一个DataAccessProvider
类,它打开与数据库的事务并提供工作单元实例,我试图将它注入过滤器属性。
documentation表示只需拨打RegisterFilterProvider()
即可,并确保已注册相关类型。它明确表示没有必要注册属性,但我已经尝试了有无。我的代码目前看起来像这样:
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.Register(x => new EntityAccessProvider())
.As<IDataAccessProvider>()
.InstancePerHttpRequest();
builder.RegisterType<DebugLogAttribute>().PropertiesAutowired();
// ^ I've tried it with and without this line
builder.RegisterFilterProvider();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
然后,文档中的示例只是在过滤器上放置一个属性,所以我也做了同样的事情:
public class DebugLogAttribute : ActionFilterAttribute
{
private IDataAccessProvider DataAccess { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext) { ... }
public override void OnActionExecuted(ActionExecutedContext filterContext) { ... }
}
文档说这一切都是必需的 - 甚至不是注入的构造函数;这是通过注入财产来完成的。但是,当我运行此代码时,DataAccess
属性始终为null
; Autofac似乎忽略了它。我知道注册工作正常,因为它正确地将EntityAccessProvider
注入我的控制器,但它不适用于属性。我错过了什么?
答案 0 :(得分:14)
IDataAccessProvider
类型的属性必须公开才能注入工作。如果您愿意,您仍然可以将DebugLogAttribute
,IDataAccessProvider
标记为内部。
[DebugLogAttribute]
public class HOmeController : Controller
{
public ActionResult Index()
{
return View();
}
}
internal class DebugLogAttribute : ActionFilterAttribute
{
public IDataAccessProvider DataAccess { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Debugger.Break();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Debugger.Break();
}
}
internal interface IDataAccessProvider {}
internal class DataAccessProvider:IDataAccessProvider {}
答案 1 :(得分:0)
我在asp dotnet核心中遇到了同样的问题,但是当前的解决方案(使其公开)似乎不起作用。我发现奇怪的是,以下评论是关于Web-api的,但是我使用的是普通的ASP.NET Core MVC(MVC6)。因此,如果有人遇到相同的问题,请尝试以下解决方案。
与MVC中的过滤器提供程序不同,Web API中的过滤器提供程序不允许您指定不应缓存过滤器实例。这意味着Web API中的所有过滤器属性实际上都是在应用程序整个生命周期内存在的单例实例。
public override async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next)
{
MyService = context.HttpContext.
RequestServices.GetService(typeof(IMyService)) as IMyService;
}