我需要访问ActionFilter
属性中的数据库上下文。如果不通过构造函数传递上下文,我该怎么做?
简短的问题是:如何像以前在ASP.NET Framework中那样将数据库上下文放在一行中?
正确的方法是使用依赖注入注册过滤器,然后使用ServiceFilterAttribute
将过滤器放入管道中。这样,您的过滤器类型将使用依赖项注入进行解析,因此您可以正常注入数据库上下文并像平常一样使用它。
public class MyActionFilter : IActionFilter
{
private readonly MyDbContext _dbContext;
public MyActionFilter(MyDbContext dbContext)
{
_dbContext = dbContext;
}
public void OnActionExecuted(ActionExecutedContext context)
{
// use _dbContext here
}
public void OnActionExecuting(ActionExecutingContext context)
{ }
}
在Startup.ConfigureServices
中注册类型:
services.AddTransient<MyActionFilter>();
然后使用ServiceFilterAttribute
激活它。作为控制器或动作的属性:
[ServiceFilter(typeof(MyActionFilter))]
public class MyController : Controller
{
// …
}
或者通过MvcOptions
像其他任何过滤器一样在全球注册:
services.AddMvc(options => {
options.Filters.Add(new ServiceFilterAttribute(typeof(MyActionFilter)));
});
然后,MyActionFilter
将在每个需要过滤器的请求上得到解析,并且数据库上下文将从依赖注入容器中注入适当的生命周期。
通常不建议您自己实例化数据库上下文(在单元测试之外)。 ASP.NET Core中有一个依赖注入容器,因此您应该在任何地方使用它,而不是自己维护对象的生命周期和依赖关系。