2016-09-22 2 views
2

두 번 이상 생성되는 Ninject 싱글 톤 범위 클래스에 문제가 있습니다. 나는 이상한 행동을 보여주는 예제로 코드를 축소했다. Handler는 Handler 생성자에 의해 수행되는 다소 복잡한 초기화를 갖는 Module로 구성된 싱글 톤입니다. 그것이 ToMethod()를 사용하여 모듈 바인딩을하는 이유입니다. Part는 또한 싱글 톤이며, Part가 생성되면 Handler가 생성된다는 것이 매우 중요합니다. 그래서 우리는 Part OnActivation 콜백에서 Handler를 요청합니다. 일부 디버그 출력을 포함하나 이상의 인스턴스를 만드는 Ninject의 InSingletonScope()

IKernel kernel = new StandardKernel(); 
kernel.Bind<Handler>().ToSelf().InSingletonScope(); 
kernel.Bind<Module>().ToMethod(x => x.Kernel.Get<Handler>().Module); 
kernel.Bind<Part>().ToSelf().InSingletonScope().OnActivation(_ => kernel.Get<Handler>()); 

전체 코드 :

[Test] 
    public void NinjectShouldCreateOnlyOneHandler() 
    { 
     IKernel kernel = new StandardKernel(); 
     kernel.Bind<Handler>().ToSelf().InSingletonScope(); 
     kernel.Bind<Module>().ToMethod(x => 
     { 
      Debug.WriteLine("Module ToMethod enter"); 
      Module module = x.Kernel.Get<Handler>().Module; 
      Debug.WriteLine("Module ToMethod exit"); 
      return module; 
     }); 
     kernel.Bind<Part>().ToSelf().InSingletonScope().OnActivation(_ => 
     { 
      Debug.WriteLine("Part OnActivation enter"); 
      kernel.Get<Handler>(); 
      Debug.WriteLine("Part OnActivation exit"); 
     }); 

     Debug.WriteLine("Get<Module>()"); 
     kernel.Get<Module>(); 
     Debug.WriteLine($"InstanceCount = {Handler.InstanceCount}"); 
     Assert.AreEqual(1, Handler.InstanceCount); 
    } 

    public class Handler 
    { 
     public static int InstanceCount { get; private set; } = 0; 

     public Handler(Part part) 
     { 
      Debug.WriteLine($"Handler ctor, InstanceCount = {++InstanceCount}"); 
      Module = new Module(part); 
     } 

     public Module Module { get; } 
    } 

    public class Module 
    { 
     public Module(Part part) 
     { 
      Debug.WriteLine("Module ctor"); 
     } 
    } 

    public class Part 
    { 
     public Part() 
     { 
      Debug.WriteLine("Part ctor"); 
     } 
    } 

디버그 출력 :

Get<Module>() 
Module ToMethod enter 
Part ctor 
Part OnActivation enter 
Handler ctor, InstanceCount = 1 
Module ctor 
Part OnActivation exit 
Handler ctor, InstanceCount = 2 
Module ctor 
Module ToMethod exit 
InstanceCount = 2 

나는 문제가 만드는 동안 우리는 처리기 인스턴스를 요청하는 것입니다 생각, 하지만 그 시점에서 생성 될 수 있기 때문에 - 왜 그 인스턴스는 다음 요청을 위해 사용되지 않습니까?

Ninject는 싱글 톤 범위 클래스의 인스턴스 두 개를 만드는 대신 예외를 던질 것을 기대합니다. 이 버그입니까, 아니면 놓친 부분이 있습니까? 우리는 Ninject v3.2.2를 사용하고 있습니다.

답변

0

개체를 만들 때 순환 종속성이 있습니다.

해서 Ninject는 Handler의 하나 개의 인스턴스를 만들 수을 시도 하지만 Handler를 인스턴스화하려고 할 때, 그것은 Part 인스턴스를 필요로 할 수 있기 때문에 Part를 만드는 단계는 Handler합니다 (OnActiviation 행동의 예를 들면을 받고있다 Part).

+0

예,하지만 OnActivation 콜백 내에 Handler *를 만들 수 있으며 저장되지 않고 원래 요청으로 반환되는 이유를 이해할 수 없습니다. 또한, Ninject가 수행 할 작업을 수행 할 수없는 경우에는 싱글 톤으로 표시된 클래스의 인스턴스를 여러 개 만드는 대신 예외를 throw해야합니다. 나는 이것을 Ninject 개발자들에게보고 할 필요가 있다고 생각한다. – Anlo

관련 문제