【发布时间】:2014-06-18 21:55:49
【问题描述】:
我有一个 Web API 应用程序,其中控制器通过依赖注入 (Unity) 将服务/存储库等注入其中。假设我有一个 IStuffService 需要当前请求的 IPrincipal(或围绕它的包装器)。
Web API 的问题似乎是当前请求/用户的唯一可靠来源是ApiController 的实例 上的Request 属性.由于 Web API 的同步特性,不能保证任何静态内容(无论是 HttpContext.Current、CallContext.Get/SetData 或 Thread.Get/SetData)都在同一个线程上。
我如何可靠地确保特定于请求的上下文通过依赖项传递,更重要的是,该操作在整个操作过程中始终保持正确的IPrincipal?
两种选择:
- 每个需要
IPrincipal的方法都将它作为方法的参数 - 这是最可靠的方法,但它也要求我在每个方法签名中都有那个东西 - 将 IPrincipal 注入到服务的 ctor 中,在每个请求上启动对象图的新实例,使用 Unity 中的 DependencyOverride:
container.Resolve(opType, new DependencyOverride(typeof(IPrincipal), principal))
选项 2 意味着我的方法签名是干净的,但这也意味着我需要确保所有依赖项都使用 TransientLifetimeManager,而不是单例甚至每线程。
有没有比我没有看到的更好的解决方案?
【问题讨论】:
-
理想情况下,您是否希望您的
IStuffService实现在所有请求中都是单例? -
@Xenolightning 但是当我进行方法调用时,服务如何获取当前的
IPrincipal? -
有趣的问题,但为什么你的控制器中的每个方法都需要
IPrincipal? -
@DavidG 我的服务中需要它(它在我的控制器中可用)。一个示例是记录哪个用户进行了更改,或者确定给定当前用户的服务调用是否合法。这是一个业务逻辑级别的决策,存在于服务中,需要知道谁在调用来做出该决策。
-
@MichaelStum 这种逻辑在
AuthorizeAttribute中不是更好吗?
标签: c# asp.net .net asp.net-web-api async-await