配置 Simple Injector 以注入当前经过身份验证的用户

Configure Simple Injector to inject current authenticated user

我有一个 class 需要根据当前经过身份验证的用户在构建时设置一个 IPrinciple 对象。

我找到了一些我试过但没有用的其他代码:

private readonly Lazy<IPrincipal> _principal;

public MyService(Lazy<IPrincipal> principal)
{
    _principal = principal;
}

然后我像这样配置了 Simple Injector:

container.Register(() => new Lazy<IPrincipal>(() => HttpContext.Current.User));

当我尝试 运行 this.

时,显然 _principal undefined/not 设置为一个对象的实例

我也试过:

container.Register(() => new Lazy<IPrincipal>(() => Thread.CurrentPrincipal));

这让我可以检查 _principal.Value.Identity.IsAuthenticated 但总是返回 false

问题的根源在于您在对象图构造期间将运行时数据注入组件。正如所解释的 here,这是个坏主意。

相反,正如参考文章所建议的那样,您应该延迟请求此运行时数据的决定,直到构建图形之后;在此运行时数据可用时。

您可以通过创建自定义 IPrincipal 实现来做到这一点:

public class HttpContextPrinciple : IPrincipal
{
    public IIdentity Identity => HttpContext.Current.User.Identity;
    public bool IsInRole(string role) => HttpContext.Current.User.IsInRole(role);
}

然后这样注册:

container.RegisterSingleton<IPrincipal>(new HttpContextPrinciple());

这允许您将 IPrincipal 直接注入 MyService 等消费者。这简化了消费者,因为他们不必处理 leaky abstractions 例如 Lazy<T>.