我們遇到了一個Ninject單例作用域類不止一次構建的問題。我將我們的代碼縮減爲一個展示奇怪行爲的例子。 Handler是一個單元,它由一個具有複雜初始化的模塊組成,由Handler構造函數執行。這就是使用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不能做我告訴它做的事情,我希望它會拋出一個異常,而不是創建一個標記爲單例的類的多個實例。我想我需要把這個報告給Ninject開發者。 – Anlo