这是示例代码:
using Ninject;
using Ninject.Activation;
using Ninject.Extensions.Factory;
using Ninject.Planning.Targets;
using System;
using System.Linq;
namespace DI
{
public interface INumberFactory
{
Test Create(int a);
}
public class Test
{
public Test(int a) { }
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel(new FuncModule());
kernel.Bind<Test>().ToSelf().WithConstructorArgument("a" , (context, target) =>
{
Console.WriteLine("I'm trying to retrieve the constructor argument");
return 0;
});
kernel.Bind<INumberFactory>().ToFactory();
// Nothing is printed, even if it logically should be
kernel.Get<INumberFactory>().Create(1);
}
}
}
我有一个简单的工厂,就我而言,就是INumberFactory。该工厂采用int参数“ a”并创建Test类的实例。我想使用传递给INumberFactory的Create方法的构造函数参数创建此实例。
我为此使用了WithConstructorArgument。我也想做一些自定义配置-这就是为什么我要使用重载,让我传递Func类型的回调的原因。我很惊讶根本没有调用回调。
看来关键是参数的名称。构造函数参数和工厂参数都被命名为“ a”。但这在两个事物被命名且相同且含义不同的情况下可能是一个问题。这就是为什么我想知道:
(1)这是错误还是预期的行为?
(2)有没有办法防止这种“自动通过”?我想完全控制传递构造函数的参数。
最佳答案
查看documentation和ToFactory()
将使Ninject创建一个动态代理,其行为与您的代码类似:
public class NumberFactory : INumberFactory
{
readonly IResolutionRoot resolutionRoot;
public NumberFactory(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
Test INumberFactory.Create(int a)
{
return this.resolutionRoot.Get<Test>(
new ConstructorArgument("a", a));
}
}
因此,它没有使用您在
WithConstructorArgument
中指定的绑定,而是将直接使用您作为Create
参数传递的值。