2010-04-05 6 views
9

.Net 3.5 프레임 워크에 Ninject 2.0을 사용하고 있습니다. 싱글 톤 바인딩에 어려움이 있습니다.Ninject : 싱글 톤 바인딩 구문?

나는 IInputReader을 구현하는 클래스 UserInputReader을 가지고 있습니다. 나는 오직이 클래스의 한 인스턴스 만 만들어지기를 원합니다.

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 : UserInputReader의 생성자에서 사용하는 IDictionary<ActionInputType, Keys>를 지정하려면 WithConstructorArgument 방법을 사용할 수 있습니다 // 승 ww.yoda.arachsys.com/csharp/singleton.html – mcliedtk

+0

동일한 어셈블리에있는 경우 private 대신 생성자를 내부로 만들 수 있습니다. 아마도 다른 어셈블리의 코드가 해당 생성자에 액세스하는 것이 염려되는 경우 광고가 약간 안전 할 수 있습니다. – jpierson

+1

'Bind (). (). InSingletonScope()' – Jaider

답변

18

물론 생성자를 비공개로 만들면 중단됩니다. 클래스 외부의 개인 생성자를 호출 할 수 없습니다!

당신이하는 일은 당신이해야 할 일입니다. 테스트 해보기 :

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

인스턴스 싱글 톤을 얻으려면 정적 필드가 필요하지 않습니다. IoC 컨테이너를 사용하는 경우 컨테이너를 통해 모든 인스턴스를 가져와야합니다.

당신이, 당신과 같이 그 값 유형을 결합 할 수있다 (즉에 대한 좋은 이유가 있는지 확실하지 않습니다) 공공 정적 필드를 원하는을 경우

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

편집가 : 싱글에

Bind<UserInputReader>().ToSelf() 
    .WithConstructorArgument("keyMapping", Constants.DEFAULT_KEY_MAPPING) 
    .InSingletonScope(); 
+0

좋습니다. 그러나 UserInputReader의 생성자에는 IDictionary 이 필요합니다. Ninject에서이를 어떻게 지정할 수 있습니까? –

+0

@Rosarch : 사전에 마커 래퍼를 만들거나 IActionKeyMap이라고 부르거나이를 사용하거나 주석에 메서드 접근법을 사용하거나 시설을 사용하여 ctor 매개 변수를 지정할 수 있습니다 (기억할 수 없음). 정확히 어떻게 :(. –

+1

그것을 얻었다 :'.WithConstructorArgument ("keyMapping",/* whatever * /);' –

0

IInputReader는 인스턴스 필드도 선언하지 않으며 인터페이스는 필드 또는 정적 필드 또는 정적 속성 (또는 정적 메서드)을 가질 수 없기 때문에이를 선언 할 수도 없습니다.

Bind 클래스는 리플렉션을 사용하지 않는 한 인스턴스 필드를 찾는다는 것을 알 수 없습니다.