- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
AuthenticationRequiredAttribute 类
public class AuthenticationRequiredAttribute : ActionFilterAttribute
{
ILoginTokenKeyApi _loginTokenKeyApi;
IMemoryCache _memoryCache;
public AuthenticationRequiredAttribute(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
_loginTokenKeyApi = new LoginTokenKeyController(new UnitOfWork());
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var memory = _memoryCache.Get(Constants.KEYNAME_FOR_AUTHENTICATED_PAGES);
string requestedPath = filterContext.HttpContext.Request.Path;
string tokenKey = filterContext.HttpContext.Session.GetString("TokenKey")?.ToString();
bool? isLoggedIn = _loginTokenKeyApi.IsLoggedInByTokenKey(tokenKey).Data;
if (isLoggedIn == null ||
!((bool)isLoggedIn) ||
!Constants.AUTHENTICATED_PAGES_FOR_NORMAL_USERS.Contains(requestedPath))
{
filterContext.Result = new JsonResult(new { HttpStatusCode.Unauthorized });
}
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
家庭 Controller
public class HomeController : Controller
{
IUserApi _userApi;
ILoginTokenKeyApi _loginTokenKey;
IMemoryCache _memoryCache;
public HomeController(IUserApi userApi, ILoginTokenKeyApi loginTokenKey, IMemoryCache memoryCache)
{
_loginTokenKey = loginTokenKey;
_userApi = userApi;
_memoryCache = memoryCache;
}
[AuthenticationRequired] // There is AN ERROR !!
public IActionResult Example()
{
return View();
}
}
错误:
Error CS7036 There is no argument given that corresponds to therequired formal parameter 'memoryCache' of'AuthenticationRequiredAttribute.AuthenticationRequiredAttribute(IMemoryCache)' Project.Ground.WebUI
我的问题实际上是:我不能在属性类中使用依赖注入(inject)。
我想在没有任何参数的情况下使用该属性。有解决办法吗?我使用依赖注入(inject),但它不能用于属性。我该如何使用它?
最佳答案
根据 the documentation ,您在这里有几个选择:
If your filters have dependencies that you need to access from DI, there are several supported approaches. You can apply your filter to a class or action method using one of the following:
ServiceFilterAttribute
TypeFilterAttribute
IFilterFactory
implemented on your attribute
如果您只是想让它快速运行,您可以只使用前两个选项之一将您的过滤器应用于 Controller 或 Controller 操作。执行此操作时,您的过滤器本身不需要是属性:
[TypeFilter(typeof(ExampleActionFilter))]
public IActionResult Example()
=> View();
ExampleActionFilter
然后可以只实现例如IAsyncActionFilter
您可以使用构造函数注入(inject)直接依赖事物:
public class ExampleActionFilter : IAsyncActionFilter
{
private readonly IMemoryCache _memoryCache;
public ExampleActionFilter(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{ … }
}
您也可以使用 [ServiceFilter]
属性来获得相同的效果,但是您还需要在您的 启动
。
如果您需要更大的灵 active ,您可以实现自己的过滤器工厂。这允许您编写工厂代码来自己创建实际的过滤器实例。上述 ExampleActionFilter
的可能实现如下所示:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ExampleActionFilterAttribute : Attribute, IFilterFactory
{
public bool IsReusable => false;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return serviceProvider.GetService<ExampleActionFilter>();
}
}
然后您可以使用 [ExampleActionFilter]
属性让 MVC 框架使用 DI 容器为您创建一个 ExampleActionFilter
的实例。
请注意,此实现与 ServiceFilterAttribute
所做的基本相同。只是自己实现它可以避免直接使用 ServiceFilterAttribute
并允许您拥有自己的属性。
最后,还有另一个快速选项可以让您完全避免构造函数注入(inject)。这使用服务定位器模式在过滤器实际运行时动态解析服务。因此,不是注入(inject)依赖项并直接使用它,而是从上下文中显式检索它:
public class ExampleActionFilter : ActionFilterAttribute
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var memoryCache = context.HttpContext.RequestServices.GetService<IMemoryCache>();
// …
}
}
关于c# - 如何在 .Net Core ActionFilterAttribute 中使用依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52724974/
我是一名优秀的程序员,十分优秀!