2016-05-25 27 views
3

我有一个类需要根据当前认证的用户设置一个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

回答

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。这简化了消费者,因为他们不必处理leaky abstractions,例如Lazy<T>

相关问题