是的,你可以这样做,但这可能不是你真正想要的。如果容器实际上不负责实例化它自己的依赖项,那么它的依赖项可能不应该共享它的构造函数参数——它只是没有意义。
我很确定我知道您要做什么,推荐的方法是专门为您的一个容器创建一个唯一的绑定,并使用WhenInjectedInto
条件绑定语法,如下例所示:
public class Hello : IHello
{
private readonly string name;
public Hello(string name)
{
this.name = name;
}
public void SayHello()
{
Console.WriteLine("Hello, {0}!", name);
}
}
这是一个接受我们要修改的构造函数参数的类,具体取决于谁要求IHello
. 假设这是一个无聊的容器类:
public class MyApp : IApp
{
private readonly IHello hello;
public MyApp(IHello hello)
{
this.hello = hello;
}
public virtual void Run()
{
hello.SayHello();
Console.ReadLine();
}
}
现在,这里是你如何做绑定:
public class MainModule : NinjectModule
{
public override void Load()
{
Bind<IApp>().To<MyApp>();
Bind<IHello>().To<Hello>()
.WithConstructorArgument("name", "Jim");
Bind<IHello>().To<Hello>()
.WhenInjectedInto<MyApp>()
.WithConstructorArgument("name", "Bob");
}
}
基本上所有这个绑定所做的就是说name
应该是“Jim” ,除非它被请求Hello
,在这种情况下它是,所以它会得到名称“Bob”。
如果你绝对确定你真的想要级联行为并且理解这是非常危险和脆弱的,你可以使用方法绑定来作弊。假设我们现在为某个未指定的目的name
向类添加了一个参数MyApp
,绑定将是:
Bind<IHello>().ToMethod(ctx =>
ctx.Kernel.Get<Hello>(ctx.Request.ParentContext.Parameters
.OfType<ConstructorArgument>()
.Where(c => c.Name == "name")
.First()));
拜托,拜托,在做之前确保你确定这是你想要的。它看起来很简单,但在简单的重构过程中也很可能会中断,而且我见过的 95% 的“自定义依赖”场景都可以使用WhenInjectedInto
绑定来解决。