2010-04-05 25 views
9

我在.NET 3.5框架中使用Ninject 2.0。我與單身綁定有困難。Ninject:Singleton綁定語法?

我有一個類UserInputReader其實施IInputReader。我只想要創建這個類的一個實例。

public class MasterEngineModule : NinjectModule 
    { 
     public override void Load() 
     { 
      // using this line and not the other two makes it work 
      //Bind<IInputReader>().ToMethod(context => new UserInputReader(Constants.DEFAULT_KEY_MAPPING)); 

      Bind<IInputReader>().To<UserInputReader>(); 
      Bind<UserInputReader>().ToSelf().InSingletonScope(); 
     } 
    } 

     static void Main(string[] args) 
     { 
      IKernel ninject = new StandardKernel(new MasterEngineModule()); 
      MasterEngine game = ninject.Get<MasterEngine>(); 
      game.Run(); 
     } 

public sealed class UserInputReader : IInputReader 
    { 
     public static readonly IInputReader Instance = new UserInputReader(Constants.DEFAULT_KEY_MAPPING); 

     // ... 

     public UserInputReader(IDictionary<ActionInputType, Keys> keyMapping) 
     { 
      this.keyMapping = keyMapping; 
     } 
} 

如果我使該構造函數爲私有,它會中斷。我在這裏做錯了什麼?

+0

對單身一些有趣的變化:HTTP:// w^ww.yoda.arachsys.com/csharp/singleton.html – mcliedtk 2010-04-05 22:26:55

+0

如果構造函數在同一個程序集中,則可以將其構造成內部而不是私有的。如果您擔心訪問該構造函數的其他程序集的代碼,那麼也許該廣告會有一點安全性。 – jpierson 2011-10-24 20:23:12

+1

'綁定()。到()。InSingletonScope()' – Jaider 2014-04-09 16:56:23

回答

18

當然,如果你使構造函數是私有的,它會中斷。你不能從課堂外面調用私人構造函數!

你在做什麼正是你應該做的。測試它:

var reader1 = ninject.Get<IInputReader>(); 
var reader2 = ninject.Get<IInputReader>(); 
Assert.AreSame(reader1, reader2); 

您不需要靜態字段來獲取實例單例。如果您使用的是IoC容器,則應該通過容器獲取所有實例。

如果希望公衆靜態字段(不知道如果有一個很好的理由),可以綁定類型的值,如:

Bind<UserInputReader>().ToConstant(UserInputReader.Instance); 

編輯:要指定IDictionary<ActionInputType, Keys>UserInputReader構造函數使用,你可以使用WithConstructorArgument方法:

​​
+0

好吧,很酷。但是UserInputReader的構造函數需要一個'IDictionary '。我如何在Ninject中指定這個? – 2010-04-05 22:32:57

+0

@Rosarch:或者你在字典周圍創建一個標記包裝器,將其稱爲'IActionKeyMap'或者其他東西,然後使用它,或者在評論中使用方法方法,或者使用這些工具來指定ctor參數(不記得究竟如何:(。 – 2010-04-05 22:47:29

+1

明白了:'.WithConstructorArgument(「keyMapping」,/ * whatever * /);' – 2010-04-05 22:50:17

0

IInputReader沒有聲明實例字段也不能,因爲接口不能有字段或靜態字段,甚至不能有靜態屬性(或靜態方法)。

Bind類無法知道它是找到實例字段(除非它使用反射)。