2010-04-05 54 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类无法知道它是找到实例字段(除非它使用反射)。