我有一个类需要根据当前经过身份验证的用户在构造上设置IPrinciple
对象。
我发现了其他一些我试过的代码,但它没有用:
private readonly Lazy<IPrincipal> _principal;
public MyService(Lazy<IPrincipal> principal)
{
_principal = principal;
}
我像这样配置了简单注入器:
container.Register(() => new Lazy<IPrincipal>(() => HttpContext.Current.User));
当我尝试运行它时,显然_principal
未定义/未设置为对象的实例。
我也尝试过:
container.Register(() => new Lazy<IPrincipal>(() => Thread.CurrentPrincipal));
这允许我检查_principal.Value.Identity.IsAuthenticated
,但始终返回false
。
答案 0 :(得分:8)
问题的根源是由于在对象图构建期间将运行时数据注入组件这一事实。正如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
等消费者。这简化了消费者,因为他们不必处理Lazy<T>
等leaky abstractions。