C# 构造函数参数。在Kernel.Get工作的地方注入中断
鉴于以下类别:C# 构造函数参数。在Kernel.Get工作的地方注入中断,c#,ninject,C#,Ninject,鉴于以下类别: interface IFoo { } class Foo : IFoo { } class Bar { public Bar(IFoo foo) { } } 以及约束力: Bind<Bar>().ToConstructor(ctx => new Bar(ctx.Inject<Foo>())); 但是,如果我将绑定更改为: Bind<Bar>().ToMethod(ctx => new Bar(ctx.Kernel.G
interface IFoo { }
class Foo : IFoo { }
class Bar
{
public Bar(IFoo foo) { }
}
以及约束力:
Bind<Bar>().ToConstructor(ctx => new Bar(ctx.Inject<Foo>()));
但是,如果我将绑定更改为:
Bind<Bar>().ToMethod(ctx => new Bar(ctx.Kernel.Get<Foo>()));
Bind().ToMethod(ctx=>newbar(ctx.Kernel.Get());
我可以按预期获得Bar
的实例
为什么我会得到那个例外?我的印象是这两个绑定几乎相同,在这两种情况下,IFoo
的实例从未激活
(非)可在此处看到工作小提琴:ninject不支持此功能。
ctx.Inject
中指定的类型必须与构造函数参数的类型完全匹配。Ninject从未实际执行您的新条(…)
,它只分析表达式以确定使用哪个构造函数以及如何注入值
有两种方法可以调整代码以使其正常工作:
- 更改
的构造函数以接收Bar
IFoo的
inteadFoo
- 将
Bar的
绑定更改为具有ToConstructor
匹配ctx.Inject()
Bar的构造函数(
),并为ctx.Inject()
创建绑定:IFoo
T
atInject
的类型必须完全匹配的文档:答案同样是否定的。我找不到关于它的任何文档。然而,由于它是开源的,我们可以再次求助于查看实现。同样,可以在中找到,其中包含:
protected IBindingWhenInNamedWithOrOnSyntax<TImplementation> InternalToConstructor<TImplementation>(
Expression<Func<IConstructorArgumentSyntax, TImplementation>> newExpression)
{
var ctorExpression = newExpression.Body as NewExpression;
if (ctorExpression == null)
{
throw new ArgumentException("The expression must be a constructor call.", "newExpression");
}
this.BindingConfiguration.ProviderCallback = StandardProvider.GetCreationCallback(ctorExpression.Type, ctorExpression.Constructor);
this.BindingConfiguration.Target = BindingTarget.Type;
this.AddConstructorArguments(ctorExpression, newExpression.Parameters[0]);
return new BindingConfigurationBuilder<TImplementation>(this.BindingConfiguration, this.ServiceNames, this.Kernel);
}
使用语法内部构造函数命名时受保护的IBinding(
表达式(新表达式)
{
var=newExpression.Body作为newExpression;
if(表达式==null)
{
抛出新ArgumentException(“表达式必须是构造函数调用。”,“newExpression”);
}
this.BindingConfiguration.ProviderCallback=StandardProvider.GetCreationCallback(ctorExpression.Type,ctorExpression.Constructor);
this.BindingConfiguration.Target=BindingTarget.Type;
this.AddConstructorArguments(ctorExpression,newExpression.Parameters[0]);
返回新的BindingConfigurationBuilder(this.BindingConfiguration、this.ServiceNames、this.Kernel);
}
你可以从这里开始,看看AddConstructorArguments
以及这些东西是如何工作的,最终你会发现它为什么会这样做;-)
(我不打算为您这样做)您能指向支持此声明的文档页面吗?我已经更新了答案,以涵盖您关于文档的问题。长话短说:这没有明确记录。
Bind<IFoo>().To<Foo>();
Bind<Bar>().ToConstructor(ctx => new Bar(ctx.Inject<IFoo>()));
public T1 Inject<T1>()
{
throw new InvalidOperationException("This method is for declaration that a parameter shall be injected only! Never call it directly.");
}
protected IBindingWhenInNamedWithOrOnSyntax<TImplementation> InternalToConstructor<TImplementation>(
Expression<Func<IConstructorArgumentSyntax, TImplementation>> newExpression)
{
var ctorExpression = newExpression.Body as NewExpression;
if (ctorExpression == null)
{
throw new ArgumentException("The expression must be a constructor call.", "newExpression");
}
this.BindingConfiguration.ProviderCallback = StandardProvider.GetCreationCallback(ctorExpression.Type, ctorExpression.Constructor);
this.BindingConfiguration.Target = BindingTarget.Type;
this.AddConstructorArguments(ctorExpression, newExpression.Parameters[0]);
return new BindingConfigurationBuilder<TImplementation>(this.BindingConfiguration, this.ServiceNames, this.Kernel);
}