2012-02-13 136 views
4

我正在編寫插件作爲插件體系結構的一部分。插件的創建方式是通過反射和CreateInstance。因此調用默認的構造函數。我無法觸及的這段代碼,我試圖找到一種明智的方式來使用DI,而無需使用框架。在沒有第三方框架的情況下實現DI

我相信我有3個選項:

我)窮人的DI(PMDI)

II)工廠模式

III)TinyIOC或類似(即處理DI一個CS文件)

我開始看PMDI,但後來一個依賴項需要另一個依賴項,所以我最終得到類似於這個醜陋,可能會變得更糟的東西:

public MyMainPluginClass() : this(new Repo(new Logger())) 
{ 

} 

public MyMainPluginClass(IRepo repo) 
{ 

} 

然後我進入了工廠模式的想法,但找不到任何體面的演示代碼。我想我會有這樣的事情:

public static FactoryUtility 
{ 
    public static IRepo GetRepo() 
    { 
    return new Repo(GetLogger()); 
    } 

    public static ILogger GetLogger() 
    { 
    return new Logger(); 
    } 
} 

    public MyMainPluginClass() : this(FactoryUtility.GetRepo()) 
    { 

    } 

    public MyMainPluginClass(IRepo repo) 
    { 

    } 

這是怎麼回事?

然後我碰到TinyIOC這是一個類,做所有的依賴註冊,但我相信它需要安裝在Program.cs中,我沒有在類庫中。如果有人使用這個任何經驗可以像這樣使用:

public MyMainPluginClass() 
    { 
     var container = TinyIoCContainer.Current; 
     container.AutoRegister(); 
     var implementation = container.Resolve<IRepo>(); 

     MyMainPluginClass(implementation); 
    } 

    public MyMainPluginClass(IRepo repo) 
    { 

    } 

是否有實現DI任何替代方法,而無需使用第三方庫,如果沒有哪種辦法從上面選擇?

注意:上面的代碼尚未編譯,只是我認爲會工作的想法。如果它們是有效的方法,請發佈更正。

+0

只是FYI;你的第三個代碼示例也基本上是窮人依賴注入。 – 2012-02-13 22:33:26

回答

1

我TinyIOC去到底。不幸的是,插件的構造函數在其實際啓動和運行之前被調用了幾次。我只是設置一個布爾值來防止多次調用註冊,因此它允許我簡單地自動註冊依賴關係,然後離開我們。

public MyMainPluginClass() : this(FactoryUtility.SetupIOC()) 
{ 

} 

public MyMainPluginClass(IRepo repo) 
{ 

} 

public static class FactoryUtility 
{ 
    private static bool Initialized = false; 

    public static IRepo SetupIOC() 
    { 
     var container = TinyIoCContainer.Current; 

     if (!Initialized) 
     { 
      container.AutoRegister(new[] { Assembly.GetExecutingAssembly() }); 

      Initialized = true; 
     } 

     var result = container.Resolve<IRepo>(); 

     return result; 
    } 
} 
2

由於您使用的是.NET 4,因此您可能需要考慮使用MEF,因爲它已內置到框架本身中。這看起來像是非常直接的DI,MEF處理得很好,因爲它主要用於擴展性。

詳情請參閱Learn More page on the MEF CodePlex site

+0

我不能使用MEF,因爲這是一個具有自己架構的遺留產品 – Jon 2012-02-13 22:04:45

+1

@Jon如果你正在實現DI部分,你可以使用任何你想要的東西......主應用程序不會使用它的事實不應該物。 – 2012-02-13 23:33:50

+0

您是否有過使用傳統架構尋找繼承MEF特定基類的插件的例子? – Jon 2012-02-14 08:37:47

0

如果我絕對不想爲DI容器添加依賴項,我喜歡使用我自己的TinyIOC(對於名稱感到抱歉,不知道它是否被採用),這對於小型項目給我一樣的語義與使用容器一樣,但在200 LOC以下時鐘。

如果你有興趣,這裏是代碼:https://gist.github.com/ad7608e2ae10b0f04229

+0

這是否會在我的默認構造函數中設置,然後我可以調用具有已解析類型的另一個構造函數? – Jon 2012-02-13 22:06:23

+0

應用程序的Ioc部分通常駐留在應用程序的基礎結構中。上面的代碼也有一個容器的概念 – flq 2012-02-14 08:33:55

+0

我同意,但正如我所提到的,我無法觸及原始應用程序,也沒有一個program.cs來設置國際奧委會容器 – Jon 2012-02-14 08:42:59

相關問題