【问题标题】:Ninject's InSingletonScope() creating more than one instanceNinject 的 InSingletonScope() 创建多个实例
【发布时间】:2017-01-30 17:10:47
【问题描述】:

我们遇到了不止一次构造 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。

【问题讨论】:

    标签: c# ninject


    【解决方案1】:

    在创建对象时你有一个循环依赖。

    Ninject 试图只创建Handler 的一个实例,但它不能,因为在尝试实例化Handler 时,它需要一个Part 实例和一个创建@987654324 的步骤@ 正在获取 Handler 的实例(Part 的 OnActiviation 操作)。

    【讨论】:

    • 是的,但是可以在 OnActivation 回调中创建一个处理程序,我不明白为什么它没有被存储并返回到原始请求而不是创建另一个?另外,如果 Ninject 不能按照我告诉它做的事情去做,我希望它会抛出异常,而不是创建标记为单例的类的多个实例。我想我需要向 Ninject 开发人员报告此情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    相关资源
    最近更新 更多