簡體   English   中英

Ninject的InSingletonScope()創建了多個實例

[英]Ninject's InSingletonScope() creating more than one instance

Ninject單例作用域類不止一次構造時遇到問題。 我已將代碼簡化為一個展示奇怪行為的示例。 Handler是一個單例,由具有一些復雜初始化的Module組成,由Handler構造函數執行。 這就是使用ToMethod()進行模塊綁定的原因。 Part也是單例,因此如果創建Part則創建Handler非常重要,這就是為什么我們在Part OnActivation回調中請求Handler的原因。

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

我猜問題是我們在創建Handler實例時會請求它,但是由於可以在那時構造它-為什么該實例不用於下一個請求?

我希望Ninject寧願引發異常,而不是創建單例作用域類的兩個實例。 這是一個錯誤還是我想念的東西? 我們正在使用Ninject v3.2.2。

創建對象時,您具有循環依賴關系。

Ninject 嘗試僅創建Handler一個實例,但是不能這樣做,因為在嘗試實例化Handler ,它需要一個Part實例,而創建Part的步驟是獲取Handler的實例( Part的OnActiviation操作)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM