2016-05-25 10 views
3

私は、現在の認証済みユーザーに基づいて、構築中のIPrincipleオブジェクトを設定する必要があるクラスを持っています。どうやら_principalがに設定されていない/未定義である現在の認証済みユーザーを注入するシンプルインジェクターを設定します

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

は、私が試したいくつかの他のコードを見つけたが、それはうまくいきませんでした:

private readonly Lazy<IPrincipal> _principal; 

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

をそして私はシンプルインジェクタそうのように構成しました私がこれを実行しようとするとオブジェクトのインスタンス。

私も試してみました:

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

は、これは私が_principal.Value.Identity.IsAuthenticatedをチェックすることができますが、常にfalseを返していました。

答えて

8

問題の根本原因は、オブジェクトグラフの構築中にランタイムデータをコンポーネントに注入することが原因です。説明したようにhere、これは悪い考えです。

代わりに、参照されている記事のアドバイスとして、グラフが作成されるまでこのランタイムデータを要求する決定を遅らせる必要があります。このランタイムデータが利用可能になった時点で

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

をそして、このようにそれを登録します:

あなたは、このようなカスタムIPrincipal実装を作成することによってこれを行うことができます。これは、あなたがMyServiceのように、消費者に直接IPrincipalを注入することができます

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

。これにより、Lazy<T>のようなleaky abstractionsを処理する必要がないため、消費者は簡単になります。

関連する問題