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

mar*_*nes 5 .net c# asp.net-mvc dependency-injection simple-injector

我有一个类需要IPrinciple根据当前经过身份验证的用户设置构造对象.

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

private readonly Lazy<IPrincipal> _principal;

public MyService(Lazy<IPrincipal> principal)
{
    _principal = principal;
}
Run Code Online (Sandbox Code Playgroud)

我像这样配置了Simple Injector:

container.Register(() => new Lazy<IPrincipal>(() => HttpContext.Current.User));
Run Code Online (Sandbox Code Playgroud)

_principal当我尝试运行它时,显然是未定义/未设置为对象的实例.

我也尝试过:

container.Register(() => new Lazy<IPrincipal>(() => Thread.CurrentPrincipal));
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*ven 8

问题的根源是在对象图构造期间将运行时数据注入组件的事实.正如这里所解释的,这是一个坏主意.

相反,作为引用的文章建议,您应该延迟决定请求此运行时数据,直到构建图形之后; 在此运行时数据可用时.

您可以通过创建这样的自定义IPrincipal实现来完成此操作:

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

并注册如下:

container.RegisterSingleton<IPrincipal>(new HttpContextPrinciple());
Run Code Online (Sandbox Code Playgroud)

这允许您IPrincipal直接注入消费者MyService.这简化了消费者,因为他们不必处理泄漏的抽象,例如Lazy<T>.