获取ninject工厂扩展以允许将工厂参数传递给依赖项

使用Ninject Factory扩展,您可以自动生成工厂,并让工厂将参数传递给类的构造函数。 以下测试通过:

public interface IBar { int Foo { get; } } public class Bar : IBar { int _foo; public Bar(int foo) { _foo = foo; } public int Foo { get { return _foo; } } } public interface IBarFactory { IBar CreateTest(int foo); } [Test] public void ExecuteTest() { var kernel = new StandardKernel(); kernel.Bind().To(); kernel.Bind().ToFactory(); var factory = kernel.Get(); var actual = factory.CreateTest(42); Assert.That(actual, Is.InstanceOf()); } 

但是,在我的特定问题中,我希望它将工厂参数传递给我正在构建的类的依赖项,而不是类本身,如下所示:

 public interface IBarContainer { IBar Bar { get; } } public class BarContainer : IBarContainer { IBar _bar; public BarContainer(IBar bar) { _bar = bar; } public IBar Bar { get { return _bar; } } } public interface ITestContainerFactory { IBarContainer CreateTestContainer(int foo); } [Test] public void ExecuteTestContainer() { var kernel = new StandardKernel(); kernel.Bind().To(); kernel.Bind().To(); kernel.Bind().ToFactory(); var factory = kernel.Get(); var actual = factory.CreateTestContainer(42); Assert.That(actual.Bar, Is.InstanceOf()); } 

此测试失败并显示以下消息:

Ninject.ActivationException:激活int时出错没有匹配的绑定可用,并且该类型不可自绑定。 激活路径:
3)将依赖项int注入到Bar类型的构造函数的参数foo中
2)将依赖关系IBar注入到BarContainer类型的构造函数的参数栏中
1)申请IBarContainer

有没有办法让工厂弄清楚我想在解析’Bar’依赖时使用传递的’foo’参数?

从Ninject.Extensions.Factory版本3.2.0开始,本机支持此版本,使用:

 Ninject.Extensions.Factory.TypeMatchingArgumentInheritanceInstanceProvider 

你可以像这样使用它:

 kernel.Bind() .ToFactory(() => new TypeMatchingArgumentInheritanceInstanceProvider()); 

如果您查看源代码 ,它将基于之前的答案 。

Hy,默认实例提供程序不使用inheritance的构造函数参数。 您可以通过编写自己的实例提供程序来更改此行为,如下所示:

 public class CustomInstanceProvider : StandardInstanceProvider { protected override ConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo, object[] arguments) { var parameters = methodInfo.GetParameters(); var constructorArguments = new ConstructorArgument[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { constructorArguments[i] = new ConstructorArgument (parameters[i].Name, arguments[i], true); } return constructorArguments; } } 

然后你只需要指示ninject使用你自己的而不是提供的。

希望有所帮助

如果我正确理解你的问题,我相信这篇Ninject Wiki文章有一个很好的例子( 工厂界面 ),关于如何使用新的.ToFactory()绑定扩展,以及如何让那些生成的工厂甚至创建构造者的对象有参数。