Ninject传递构造函数值
使用Ninject,您如何配置内核,以便我可以定义哪些构造函数值传递到对象的实例化?
我在模块中配置了以下内容:
Bind() .To() .InSingletonScope() .Named("LIVE"); Bind() .To() .InSingletonScope() .Named("LIVE") .WithConstructorArgument( "service1", Kernel.Get("LIVE"));
Service2Impl接受IService1的构造函数参数,但我希望它来自容器。 我也想要命名绑定,因为我的代码将在运行时针对不同的版本。
这似乎有效,但它是实现我想做的正确方法吗? 我是否应该在不使用命名绑定的情况下实现并将不同的配置模块连接到内核中?
编辑
我现在使用ToMethod()方法指定一个委托,以根据特定类型的请求进行调用。 这看起来好一点,因为如果构造函数配置错误,我将得到编译时警告,而不是必须知道我首先传递的参数的名称。
谢谢
我建议使用像这样的lambda的WithConstructorParameter
重载:
Bind() .To() .InSingletonScope() .Named("LIVE") .WithConstructorArgument( "service1", ctx => ctx.Kernel.Get("LIVE"));
这将确保IServive1
的分辨率在激活IServive1
时发生,而不是在创建容器时启动时发生。 虽然在你的情况下它并不重要,因为Service1Impl
是单例,但是在你最初编写它时可能会产生副作用:
-
必须已存在
WithConstructorArgument
注入的依赖项绑定。 这意味着所有绑定都必须按特定顺序完成。 当涉及多个模块时,这会产生棘手的问题。 -
使用自定义范围时可能会出现范围问题。 Ninject 2.0引入了缓存和收集范围管理,绑定到常量极有可能使其陷入混乱。
我最后使用了ToMethod,它允许我用构造函数构造所需的实例,以便维护编译时错误。
例如:
.ToMethod(Func method) Bind().ToMethod(context => new Sword());
看来你正在以错误的方式看待这个问题。 如果将服务1作为构造函数参数,则Ninject会自动将服务1注入服务2。 在这种情况下,不需要WithConstructorArgument。
如果有多个IService1你应该选择条件。 例如WhenParentNamed(…)
也许供应商可以帮助您。 将IService2绑定到提供者。 在Provider的Create方法中,使用Kernel.Get(“LIVE”)创建Service2Impl实例。
请参阅以下链接以了解如何使用提供程序https://github.com/ninject/ninject/wiki/Providers%2C-Factory-Methods-and-the-Activation-Context
我认为ToConstant()
更清晰, InSingletonScope
是隐含的:
Bind().ToConstant(new Service2Impl(argument))) .Named("LIVE");