我刚刚从Ninject更改为TinyIoC以进行依赖注入,而我在构造函数注入方面遇到了麻烦。
我已设法将其简化为此代码段:
public interface IBar { }
public class Foo
{
public Foo(IBar bar) { }
}
public class Bar : IBar
{
public Bar(string value) { }
}
class Program
{
static void Main(string[] args)
{
var container = TinyIoCContainer.Current;
string value = "test";
container.Register<IBar, Bar>().UsingConstructor(() => new Bar(value));
var foo = container.Resolve<Foo>();
Console.WriteLine(foo.GetType());
}
}
导致抛出TinyIoCResolutionException:
"Unable to resolve type: TinyIoCTestApp.Foo"
并且该异常内部是一系列内部异常:
"Unable to resolve type: TinyIoCTestApp.Bar"
"Unable to resolve type: System.String"
"Unable to resolve type: System.Char[]"
"Value cannot be null.\r\nParameter name: key"
我使用构造函数注入的方式有问题吗?我知道我可以打电话了
container.Register<IBar, Bar>(new Bar(value));
这确实有效,但结果是Bar的全局实例,而不是我所追求的。
有什么想法吗?
答案 0 :(得分:7)
我不熟悉TinyIOC,但我想我可以回答你的问题。
UsingConstructor
注册一个lambda,它指向TinyIOC将用于进行自动构造函数注入的构造函数(ctor(string)
)。 TinyIOC将分析构造函数参数,找到类型System.String
的参数并尝试解析该类型。由于您尚未明确注册System.String
(您不应该这样做),因此解析IBar
(以及Foo
)会失败。
你做出的错误假设是TinyIOC会执行你的() => new Bar(value))
lambda,而不会。如果您查看UsingConstructor
方法,则可以看到它需要Expression<Func<T>>
而不是Func<T>
。
您想要的是注册进行创建的工厂代理。我希望TinyIOC包含一个方法。它可能看起来像这样:
container.Register<IBar>(() => new Bar(value));