gpt4 book ai didi

c# - Ninject 的 InSingletonScope() 创建多个实例

转载 作者:太空宇宙 更新时间:2023-11-03 15:14:20 25 4
gpt4 key购买 nike

我们在多次构造 Ninject 单例作用域类时遇到问题。我已将我们的代码缩减为一个展示奇怪行为的示例。 Handler 是一个单例,由 Module 组成,初始化有些复杂,由 Handler 构造函数执行。这就是使用 ToMethod() 进行模块绑定(bind)的原因。 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 操作)。

关于c# - Ninject 的 InSingletonScope() 创建多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39633694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com