Mil*_*hev 3 dependency-injection custom-action-filter actionfilterattribute asp.net-core
根据这里的官方文档:
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#authorization-filters
ActionFilter要在 ASP.NET Core 中实现自定义,我有三种选择:
但对于这三个人来说:
不应与依赖于生命周期而非单例服务的过滤器一起使用。
那么如何在我的自定义中注入范围服务呢ActionFilter?我可以轻松地从当前获得范围服务,HttpContext如下所示:
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
ISubscriptionHelper subscriptionHelper =
actionContext.HttpContext.RequestServices
.GetRequiredService<ISubscriptionHelper>();
}
Run Code Online (Sandbox Code Playgroud)
但后来我想知道我是否做错了什么?在自定义 ActionFilterAttribute 中依赖范围服务的正确方法是什么?
解析来自 的服务HttpContext.RequestServices将正确解析作用域和瞬态实例,而不会导致任何问题,例如强制依赖关系。如果已解析的组件实现了IDisposable,它们将在请求结束时被处理。ASP.NET Core 将当前对象传递HttpContext给过滤器的OnActionExecuting方法,并HttpContext提供对 DI 容器的访问。
这与将这些服务注入到构造函数中完全不同,因为操作过滤器将在应用程序的生命周期内进行缓存。因此,存储在私有字段中的任何依赖项都将与该过滤器一样长久存在。这导致了所谓的俘虏依赖问题。
\n访问 DI 容器(这HttpContext.RequestServices是进入 DI 容器的网关)的代码应集中在应用程序启动路径\xe2\x80\x94(所谓的组合根)的基础设施代码中。访问组合根外部的 DI 容器不可避免地会导致服务定位器反模式\xe2\x80\x94,这不应掉以轻心。
为了防止这种情况,建议使操作过滤器内的代码量尽可能小,并将过滤器实现为Humble Object。这意味着过滤器内的唯一代码行最好如下:
\nactionContext.HttpContext.RequestServices\n .GetRequiredService<ISomeService>() // resolve service\n .DoSomeOperation(); // delegate work to service\nRun Code Online (Sandbox Code Playgroud)\n这意味着所有(应用程序)逻辑都转移到ISomeService实现中,允许操作过滤器成为一个低级对象。
| 归档时间: |
|
| 查看次数: |
1342 次 |
| 最近记录: |