2013-05-31 3 views
8

私は静的なクラスを持っており、インスタンスをいくつか注入する必要があります。静的クラスは静的コンストラクターを持つことができますが、パラメーターなしでなければなりません。だから、私はそれに何かを差し伸べるべきですか?Ninjectクラスと静的クラス - どのように?

シングルトンを作成したくありません。私は静的クラスを持ちたいと思っています。そのメソッドの1つは、注入すべきインスタンスに作用します。ベローは私が必要とするものの例です。

public static class AuthenticationHelper 
{ 
    // Fields. 
    private static object _lock = new object(); 
    private static readonly UserBusiness _userBusiness; // <-- this field needs to be injected. 

    // Public properties. 
    public static User CurrentUser 
    { 
     get 
     { 
      if (IsAuthenticated) 
      { 
       User user = (User)Context.Session[SessionKeys.CURRENT_USER]; 

       if (user == null) 
       { 
        lock (_lock) 
        { 
         if (user == null) 
         { 
          user = _userBusiness.Find(CurrentUserId); 
          Context.Session[SessionKeys.CURRENT_USER] = user; 
         } 
        } 
       } 

       return user; 
      } 

      return null; 
     } 
    } 
    public static int CurrentUserId { get; /* implementation omitted for brevity */ } 
    public static bool IsAuthenticated { get; /* implementation omitted for brevity */ } 
} 

背景情報:これはMVC4アプリケーションですので、私はninject.mvc3プラグインを使用しています。

PS:Ninjectと静的メソッドに関するいくつかの質問がありましたが、そのような問題に対処していないようです。

ありがとうございます。

答えて

16

しないでください。独自の依存関係を必要とする静的クラスを使用しないでください。これにより、テストがより困難になり、このAuthenticationHelperに依存する他の型はコンストラクタにそれを含めることができなくなります。つまり、依存するという事実を隠すことになります。

AuthenticationHelperを非静的にして、IAuthenticationHelperインターフェイスを実装し、すべての依存関係をパブリックコンストラクタに挿入します。

しかし、そのクラスを静的に保つことを主張するなら(それは本当に悪い考えです)、静的なInitialize(UserBusiness userBusiness)メソッドを作成し、アプリケーションのスタートアップパスでこのメソッドを呼び出します。 DIコンテナにこの静的メソッドを呼び出させることはできません。 1.それは悪い考えです。2.このような静的メソッドは一度呼び出す必要があるだけなので、コンテナに自動ワイヤリングをさせても実際には役に立ちません。

+0

Context.Session [CURRENT_USER]要素へのアクセスをロックすることですので。私はそれがとても悪い習慣であることに気づいていませんでしたが、あなたの説明で私は今それを分かりやすくして、あなたの助言に従います。とにかく、他のオプションがない場合、これを回避する方法を知っておくとよいでしょう。ありがとう! –

+1

それは本当ですが、時にはできません。例えば、依存性注入を従来のアプリケーションに導入する場合、小さなステップで移動する必要があります。そのような一時的なステップの上にこのような解決策があります。それは醜いです、それは技術的な深さですが、一時的です(少なくともそれはすべきです)。しかし、あなたのアプリケーションがすでにDIを使用して構築されている場合、これを行う理由はまったくありません。 – Steven

1

2つの "if(user == null)"行の間で変更されないローカル変数 "user"へのアクセスをロックするので、ロックは完全に役に立たない。

あなたの意図は..私は見

  User user = (User)Context.Session[SessionKeys.CURRENT_USER]; 

      if (user == null) 
      { 
       lock (_lock) 
       { 
        user = (User)Context.Session[SessionKeys.CURRENT_USER]; 
        if (user == null) 
        { 
         user = _userBusiness.Find(CurrentUserId); 
         Context.Session[SessionKeys.CURRENT_USER] = user; 
        } 
       } 
      } 
関連する問題