为什么 Ninject 在我指定了具有常量值参数的构造函数时坚持要对 Bool 进行绑定?
Why does Ninject insist on having a binding for Bool when I've specified a constructor with a constant value parameter?
我 运行 遇到了一个 Ninject 问题,我似乎不太了解它的深度。也许你可以看到我遗漏的一些明显的东西。我收到一个绑定错误,它希望我对 Bool:
进行绑定
Ninject.ActivationException: 错误激活 bool
没有可用的匹配绑定,并且该类型不可自绑定。
激活路径:
5) 依赖 bool 注入到 SimulatorStateMachine 类型的构造函数的参数 realTime 中
4) 将依赖项 ISimulatorStateTriggers 注入 InputParser 类型构造函数的参数 stateMachine
3)将依赖InputParser注入到SimulatorCommunicationsChannel类型构造函数的参数解析器中
2) 将依赖项 ICommunicationChannel 注入 属性 SimulatorContext 类型的通道
1)请求SimulatorContext
建议:
1) 确保您已经为 bool 定义了一个绑定。
2) 如果绑定是在模块中定义的,确保模块已经加载到内核中。
3) 确保您没有意外创建多个内核。
4) 如果您使用构造函数参数,请确保参数名称与构造函数参数名称相匹配。
5) 如果您使用自动模块加载,确保搜索路径和过滤器是正确的。
在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings)
在 Ninject.KernelBase.Resolve(IRequest 请求)
在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级)
在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标)
在 Ninject.Activation.Providers.StandardProvider.c__DisplayClass15_0.b__0(ITarget 目标)
在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
在 System.Linq.Buffer`1..ctor(IEnumerable`1 来源)
在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 来源)
在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文)
在 Ninject.Activation.Context.ResolveInternal(对象范围)
在 Ninject.Activation.Context.Resolve()
在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings)
在 Ninject.KernelBase.Resolve(IRequest 请求)
在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级)
在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标)
在 Ninject.Activation.Providers.StandardProvider.c__DisplayClass15_0.b__0(ITarget 目标)
在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
在 System.Linq.Buffer`1..ctor(IEnumerable`1 来源)
在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 来源)
在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文)
在 Ninject.Activation.Context.ResolveInternal(对象范围)
在 Ninject.Activation.Context.Resolve()
在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings)
在 Ninject.KernelBase.Resolve(IRequest 请求)
在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级)
在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标)
在 Ninject.Activation.Providers.StandardProvider.c__DisplayClass15_0.b__0(ITarget 目标)
在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
在 System.Linq.Buffer`1..ctor(IEnumerable`1 来源)
在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 来源)
在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文)
在 Ninject.Activation.Context.ResolveInternal(对象范围)
在 Ninject.Activation.Context.Resolve()
在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings)
在 Ninject.KernelBase.Resolve(IRequest 请求)
在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级)
在 Ninject.Activation.Strategies.PropertyInjectionStrategy.GetValue(IContext 上下文、ITarget 目标、IEnumerable`1 allPropertyValues)
在 Ninject.Activation.Strategies.PropertyInjectionStrategy.Activate(IContext 上下文,InstanceReference 引用)
在 Ninject.Activation.Pipeline.c__DisplayClass6_0.b__0(IActivationStrategy s)
在 Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 系列,Action`1 动作)
在 Ninject.Activation.Pipeline.Activate(IContext 上下文,InstanceReference 引用)
在 Ninject.Activation.Context.ResolveInternal(对象范围)
在 Ninject.Activation.Context.Resolve()
在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings)
在 Ninject.KernelBase.Resolve(IRequest 请求)
在 Ninject.ResolutionExtensions.GetResolutionIterator(IResolutionRoot 根、类型服务、Func`2 约束、IEnumerable`1 参数、Boolean isOptional、Boolean isUnique)
在 Ninject.ResolutionExtensions.Get[T](IResolutionRoot 根,IParameter[] 参数)
在 TA.SnapCap.Specifications.Contexts.SimulatorTestContextBuilder.Build() 中 C:\Users\Tim\source\repos\ta.snapcap\TA.SnapCap.Specifications\Contexts\SimulatorTestContextBuilder.cs: 第 44 行
在 TA.SnapCap.Specifications.SimulatorSpecs.when_creating_a_fast_simulator.c.b__5_0() 中 C:\Users\Tim\source\repos\ta.snapcap\TA.SnapCap.Specifications\SimulatorSpecs\CreationSpecs.cs: 第 32 行
我不明白为什么需要它。正在构造的对象 SimulatorStateMachine
具有到构造函数的特定绑定,该构造函数使用常量值作为 bool
参数。我也尝试过使用 .WithConstructorArgument()
.
的变体
我的整个作文根都包含在下面。如果我取消注释 Bind<bool>().ToConstant(false)
行,那么错误就会消失(但如果这当然不是我需要的行为)。很明显 Ninject 不知何故没有使用我指定的构造函数。你能明白为什么会这样吗?我不能,而且我有点代码盲...
using System;
using Ninject;
using Ninject.Modules;
using NodaTime;
using TA.Ascom.ReactiveCommunications;
using TA.SnapCap.HardwareSimulator;
namespace TA.SnapCap.Specifications.Contexts
{
class SimulatorTestContextBuilder : NinjectModule
{
private readonly IKernel testKernel = new StandardKernel();
string connectionString = "Simulator:Fast";
Action<SimulatorStateMachine>
initializeStateMachine = machine => { }; // called to initialize the state machine. DO nothing by default.
bool openChannel;
/// <inheritdoc />
public override void Load()
{
//Bind<bool>().ToConstant(false);
Bind<SimulatorStateMachine>().ToMethod(ctx => new SimulatorStateMachine(true, SystemClock.Instance));
Bind<IClock>().ToMethod(_ => SystemClock.Instance).InSingletonScope();
Bind<SimulatorEndpoint>()
.ToMethod(ctx => SimulatorEndpoint.FromConnectionString(connectionString))
.InSingletonScope();
Bind<DeviceEndpoint>().To<SimulatorEndpoint>().InSingletonScope();
Bind<InputParser>().ToSelf().InSingletonScope();
Bind<ISimulatorStateTriggers>().To<SimulatorStateMachine>().InSingletonScope();
Bind<SimulatorCommunicationsChannel>().ToSelf().InSingletonScope();
Bind<ICommunicationChannel>().To<SimulatorCommunicationsChannel>().InSingletonScope();
Bind<SimulatorContext>().ToSelf().InSingletonScope();
}
public SimulatorContext Build()
{
testKernel.Load(this);
var context = testKernel.Get<SimulatorContext>();
context.SimulatorChannel.IsOpen = openChannel;
initializeStateMachine(context.Simulator);
return context;
}
public SimulatorTestContextBuilder WithFastSimulator()
{
connectionString = "Simulator:Fast";
return this;
}
public SimulatorTestContextBuilder WithRealtimeSimulator()
{
connectionString = "Simulator:Realtime";
return this;
}
public SimulatorTestContextBuilder WithOpenChannel()
{
openChannel = true;
return this;
}
public SimulatorTestContextBuilder InClosedState()
{
initializeStateMachine = machine =>
machine.Initialize(new StateClosed(machine), testKernel.Get<InputParser>());
return this;
}
}
}
问题出在您对 ISimulatorStateTriggers
的绑定上。
应该是:
Bind<ISimulatorStateTriggers>()
.ToMethod(ctx => new SimulatorStateMachine(yourChoiceOfBoolValue, SystemClock.Instance))
.InSingletonScope();
只有当您要解析 SimulatorStateMachine
时才会使用您对 SimulatorStateMachine
的绑定,而此处不是这种情况。在这种情况下,绑定不是构造函数的重载。
我 运行 遇到了一个 Ninject 问题,我似乎不太了解它的深度。也许你可以看到我遗漏的一些明显的东西。我收到一个绑定错误,它希望我对 Bool:
进行绑定Ninject.ActivationException: 错误激活 bool 没有可用的匹配绑定,并且该类型不可自绑定。 激活路径: 5) 依赖 bool 注入到 SimulatorStateMachine 类型的构造函数的参数 realTime 中 4) 将依赖项 ISimulatorStateTriggers 注入 InputParser 类型构造函数的参数 stateMachine 3)将依赖InputParser注入到SimulatorCommunicationsChannel类型构造函数的参数解析器中 2) 将依赖项 ICommunicationChannel 注入 属性 SimulatorContext 类型的通道 1)请求SimulatorContext 建议: 1) 确保您已经为 bool 定义了一个绑定。 2) 如果绑定是在模块中定义的,确保模块已经加载到内核中。 3) 确保您没有意外创建多个内核。 4) 如果您使用构造函数参数,请确保参数名称与构造函数参数名称相匹配。 5) 如果您使用自动模块加载,确保搜索路径和过滤器是正确的。 在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings) 在 Ninject.KernelBase.Resolve(IRequest 请求) 在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级) 在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标) 在 Ninject.Activation.Providers.StandardProvider.c__DisplayClass15_0.b__0(ITarget 目标) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Buffer`1..ctor(IEnumerable`1 来源) 在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 来源) 在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文) 在 Ninject.Activation.Context.ResolveInternal(对象范围) 在 Ninject.Activation.Context.Resolve() 在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings) 在 Ninject.KernelBase.Resolve(IRequest 请求) 在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级) 在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标) 在 Ninject.Activation.Providers.StandardProvider.c__DisplayClass15_0.b__0(ITarget 目标) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Buffer`1..ctor(IEnumerable`1 来源) 在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 来源) 在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文) 在 Ninject.Activation.Context.ResolveInternal(对象范围) 在 Ninject.Activation.Context.Resolve() 在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings) 在 Ninject.KernelBase.Resolve(IRequest 请求) 在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级) 在 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标) 在 Ninject.Activation.Providers.StandardProvider.c__DisplayClass15_0.b__0(ITarget 目标) 在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 在 System.Linq.Buffer`1..ctor(IEnumerable`1 来源) 在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 来源) 在 Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文) 在 Ninject.Activation.Context.ResolveInternal(对象范围) 在 Ninject.Activation.Context.Resolve() 在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings) 在 Ninject.KernelBase.Resolve(IRequest 请求) 在 Ninject.Planning.Targets.Target`1.ResolveWithin(IContext 父级) 在 Ninject.Activation.Strategies.PropertyInjectionStrategy.GetValue(IContext 上下文、ITarget 目标、IEnumerable`1 allPropertyValues) 在 Ninject.Activation.Strategies.PropertyInjectionStrategy.Activate(IContext 上下文,InstanceReference 引用) 在 Ninject.Activation.Pipeline.c__DisplayClass6_0.b__0(IActivationStrategy s) 在 Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 系列,Action`1 动作) 在 Ninject.Activation.Pipeline.Activate(IContext 上下文,InstanceReference 引用) 在 Ninject.Activation.Context.ResolveInternal(对象范围) 在 Ninject.Activation.Context.Resolve() 在 Ninject.KernelBase.Resolve(IRequest 请求,布尔 handleMissingBindings) 在 Ninject.KernelBase.Resolve(IRequest 请求) 在 Ninject.ResolutionExtensions.GetResolutionIterator(IResolutionRoot 根、类型服务、Func`2 约束、IEnumerable`1 参数、Boolean isOptional、Boolean isUnique) 在 Ninject.ResolutionExtensions.Get[T](IResolutionRoot 根,IParameter[] 参数) 在 TA.SnapCap.Specifications.Contexts.SimulatorTestContextBuilder.Build() 中 C:\Users\Tim\source\repos\ta.snapcap\TA.SnapCap.Specifications\Contexts\SimulatorTestContextBuilder.cs: 第 44 行 在 TA.SnapCap.Specifications.SimulatorSpecs.when_creating_a_fast_simulator.c.b__5_0() 中 C:\Users\Tim\source\repos\ta.snapcap\TA.SnapCap.Specifications\SimulatorSpecs\CreationSpecs.cs: 第 32 行
我不明白为什么需要它。正在构造的对象 SimulatorStateMachine
具有到构造函数的特定绑定,该构造函数使用常量值作为 bool
参数。我也尝试过使用 .WithConstructorArgument()
.
我的整个作文根都包含在下面。如果我取消注释 Bind<bool>().ToConstant(false)
行,那么错误就会消失(但如果这当然不是我需要的行为)。很明显 Ninject 不知何故没有使用我指定的构造函数。你能明白为什么会这样吗?我不能,而且我有点代码盲...
using System;
using Ninject;
using Ninject.Modules;
using NodaTime;
using TA.Ascom.ReactiveCommunications;
using TA.SnapCap.HardwareSimulator;
namespace TA.SnapCap.Specifications.Contexts
{
class SimulatorTestContextBuilder : NinjectModule
{
private readonly IKernel testKernel = new StandardKernel();
string connectionString = "Simulator:Fast";
Action<SimulatorStateMachine>
initializeStateMachine = machine => { }; // called to initialize the state machine. DO nothing by default.
bool openChannel;
/// <inheritdoc />
public override void Load()
{
//Bind<bool>().ToConstant(false);
Bind<SimulatorStateMachine>().ToMethod(ctx => new SimulatorStateMachine(true, SystemClock.Instance));
Bind<IClock>().ToMethod(_ => SystemClock.Instance).InSingletonScope();
Bind<SimulatorEndpoint>()
.ToMethod(ctx => SimulatorEndpoint.FromConnectionString(connectionString))
.InSingletonScope();
Bind<DeviceEndpoint>().To<SimulatorEndpoint>().InSingletonScope();
Bind<InputParser>().ToSelf().InSingletonScope();
Bind<ISimulatorStateTriggers>().To<SimulatorStateMachine>().InSingletonScope();
Bind<SimulatorCommunicationsChannel>().ToSelf().InSingletonScope();
Bind<ICommunicationChannel>().To<SimulatorCommunicationsChannel>().InSingletonScope();
Bind<SimulatorContext>().ToSelf().InSingletonScope();
}
public SimulatorContext Build()
{
testKernel.Load(this);
var context = testKernel.Get<SimulatorContext>();
context.SimulatorChannel.IsOpen = openChannel;
initializeStateMachine(context.Simulator);
return context;
}
public SimulatorTestContextBuilder WithFastSimulator()
{
connectionString = "Simulator:Fast";
return this;
}
public SimulatorTestContextBuilder WithRealtimeSimulator()
{
connectionString = "Simulator:Realtime";
return this;
}
public SimulatorTestContextBuilder WithOpenChannel()
{
openChannel = true;
return this;
}
public SimulatorTestContextBuilder InClosedState()
{
initializeStateMachine = machine =>
machine.Initialize(new StateClosed(machine), testKernel.Get<InputParser>());
return this;
}
}
}
问题出在您对 ISimulatorStateTriggers
的绑定上。
应该是:
Bind<ISimulatorStateTriggers>()
.ToMethod(ctx => new SimulatorStateMachine(yourChoiceOfBoolValue, SystemClock.Instance))
.InSingletonScope();
只有当您要解析 SimulatorStateMachine
时才会使用您对 SimulatorStateMachine
的绑定,而此处不是这种情况。在这种情况下,绑定不是构造函数的重载。