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