2012-01-23 45 views
6

我要尋找一個非常簡單,重量輕IoC容器其C#源可以包含在我自己的項目(因此不會外部參考)。項目 - 嵌入式IOC容器

原因是我正在編寫一個基礎架構,並希望提供一個.dll文件,而不需要任何額外的依賴關係。

我也不想ILMerge我與IOC大會總成..

我想到了MEF,其他一些建議嗎?

+0

您可能想要標記此.net以獲取更多建議。 –

+1

看看這個問題:http://stackoverflow.com/questions/2515124/whats-the-simplest-ioc-container-for-c有一個在線的例子 –

+6

如果你正在編寫一個庫,你不應該完全可以使用DI容器:http://stackoverflow.com/questions/2045904/dependency-inject-di-friendly-library/2047657#2047657 –

回答

3

如果您使用的是.NET 4.0,則包含MEF。

對於.NET 2,我曾經使用接口和Reflection寫過類似的東西。有很多教程描述了這個過程。即使您可以使用MEF,仍然值得嘗試一些反思教程,因爲這是MEF如何在其下工作的。

也檢查出this問題,它有一些很好的答案。 TinyIoC看起來像它只是一個單一的源文件。

+0

感謝TinyIoC。看起來像我正在尋找的。 – dux2

0

我非常喜歡Castle.Windsor它是開源的,所以你可以在相關的代碼文件添加到您的項目

+2

Windsor不是我定義的一個輕量級容器。它包括大約4個程序集和許多源文件/類。 – dux2

0

這不是真的那麼難推出自己的容器,這取決於你所需要的功能類型。然而,這樣做很容易造成泄漏,所以我想你可能會想要使用經過測試和嘗試的解決方案。

MEF被某些人用作容器,但其他人則說MEF is not an IOC container,實質上MEF被設計成插件架構而不是依賴注入容器。

考慮到這一切,我會建議您在應用程序中嵌入您選擇的容器的完整源代碼,或使用工具將它的程序集合併到您自己的程序集中。 ILMerge是一個可以做到的工具,大多數商業混淆器都可以幫助你做到這一點。如果您正在構建商業圖書館或應用程序,我肯定會推薦使用適當的混淆器。

+0

正如我在我的問題中所述,我願意將容器的源代碼嵌入到我自己的項目中,但我正在尋找具有最少數量的文件和類的測試容器。請不要ILMerge。 – dux2

+0

容器的要求是什麼?你需要什麼樣的生命週期支持?你需要XML配置,流暢的配置API還是你很樂意明確配置每種類型? –

+0

我想通過代碼配置容器。希望支持單身和瞬態生命週期。 – dux2

3

如果你不需要任何幻想,一個DI容器可真短:

public class Container 
{ 
    private readonly Dictionary<Type,Func<Container,object>> factories; 
    private readonly Dictionary<Type,object> cache; 

    public Container() 
    { 
     this.factories = new Dictionary<Type,Func<Container,object>>(); 
     this.cache = new Dictionary<Type,object>(); 
    } 

    public void Register<TContract>(Func<Container,TContract> factory) 
    { 
     // wrap in lambda which returns object instead of TContract 
     factories[typeof(TContract)] = c => factory(c); 
    } 

    public TContract Get<TContract>() 
    { 
     var contract = typeof(TContract); 
     if (!cache.ContainsKey(contract)) 
     { 
      this.cache[contract] = this.factories[contract](this); 
     } 
     return (TContract)this.cache[contract]; 
    } 
} 

,你會使用這樣的:

var container = new Container(); 
container.Register<ICar>(c => new Car(
    c.Get<IEngine>(), c.Get<IWheel>())); 
container.Register<IWheel>(c => new Wheel()); 
container.Register<IEngine>(c => new Engine()); 

var car = container.Get<ICar>(); 

更簡約是做的依賴無容器注射:

IWheel wheel = new Wheel(); 
IEngine engine = new Engine(); 
ICar car = new Car(engine, wheel); 

但是,對於複雜的對象圖,它可以快速得到compli在重構期間保持正確的施工順序。容器沒有這個問題。