使用TinyIoC构造函数注入

And*_*ewG 4 c# dependency-injection constructor-injection tinyioc

我刚从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());
    }
}
Run Code Online (Sandbox Code Playgroud)

这会导致抛出TinyIoCResolutionException:

"Unable to resolve type: TinyIoCTestApp.Foo"
Run Code Online (Sandbox Code Playgroud)

在该异常内部是一系列内部异常:

"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"
Run Code Online (Sandbox Code Playgroud)

我使用构造函数注入的方式有问题吗?我知道我可以打电话

container.Register<IBar, Bar>(new Bar(value));
Run Code Online (Sandbox Code Playgroud)

这确实有效,但结果是Bar的全局实例,这不是我追求的.

有任何想法吗?

Ste*_*ven 8

我不熟悉TinyIOC,但我想我可以回答你的问题.

UsingConstructor寄存器指向在一个构造的λ(所述ctor(string)),该TinyIOC将用来做自动构造注入.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));
Run Code Online (Sandbox Code Playgroud)

  • 是的,UsingConstructor是一种选择使用哪种构造函数的方法,99%的时间都不是必需的.你想要的是Register重载,它接受Func <TinyIoCContainer,NamedParameterOverloads,object>并提供一个简单的工厂来返回你的新Bar. (2认同)