2012-02-08 122 views
4

我剛從Ninject更改爲TinyIoC進行依賴注入,我在構造函數注入時遇到了問題。構造函數注入與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" 

我在使用構造函數的方式有什麼問題嗎jection?我知道我可以打電話

container.Register<IBar, Bar>(new Bar(value)); 

而且確實工作,但結果是酒吧的全局實例這不是我後。

任何想法?

+0

另外:在共同我使用TinyIoC從GitHub(https://github.com/grumpydev/TinyIoC) – AndrewG 2012-02-08 23:04:16

+0

搞笑,背後TinyIoC的基本原理有很大與的[簡單注射器](http://simpleinjector.codeplex.com)。 – Steven 2012-02-09 08:53:47

+1

@Steven @斯蒂文,我們都被稱爲史蒂文..怪異的:-P – 2012-02-09 09:08:03

回答

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)); 
+2

是的,UsingConstructor是一種方法來選擇使用哪個構造函數和99%的時間不是必需的。你想要的是寄存器重載,它使用Func 並提供一個簡單的工廠來返回你的新Bar。 – 2012-02-09 09:07:32

+0

我同意。 '只有當你的類型有多個構造函數時,'UsingConstructor'纔有用,在做DI時通常應該避免這種構造函數。因此我甚至留下了Simple Injector的構造函數選擇功能。 – Steven 2012-02-09 09:13:46

+1

好吧,多個構造函數對於TinyIoC來說通常都很好,因爲它需要「我可以成功解析的最貪婪的構造函數」方法,但有些情況下您想重寫該構造函數。 – 2012-02-09 09:16:52