2013-05-06 64 views
13

目前我正在嘗試一點與依賴注入容器,這一次與Unity。依賴注入和其他構造參數 - 不好的做法?

考慮到如下界面:

public interface IPodcastCommService 
{ 
    void Download(); 

    void Upload(); 
} 

和下面的實現:

public class PodcastService 
{ 
    private IPodcastCommService commservice; 
    private String url; 

    public PodcastService(String url, IPodcastCommService commservice) 
    { 
     this.commservice = commservice; 
     this.url = url; 
    } 
} 

因爲構造的,我一直在尋找一個解決參數傳遞給它,發現它:

var p = container.Resolve<IPodcastCommService>(new ParameterOverride("url", myUrl)); 

到目前爲止好,但在同一時間我讀了這是多麼糟糕,以及如何這個班的設計不錯,是的,它看起來有點難看。但是,我怎樣才能以優雅的方式將參數傳遞給類?

我的第一個想法是做它作爲一個屬性,但然後我必須檢查每次我需要它已經給出的Url。

更新: 一個例子,在那裏我閱讀,這是不好的設計,是這樣的:

但也有可能是,你必須通過在解析操作的自定義構造函數的參數情況。有人可能會爭辯說,這種糟糕的體系結構尖叫,但有一些情況,如將DI容器帶入可能需要這些操作的遺留系統。

來源:http://mikaelkoskinen.net/unity-passing-constructor-parameters-to-resolve/

+1

你不介意告訴我,你有紅色的,這是不好的設計?因爲我實際上認爲這種設計是最好的你會得到。 – Egi 2013-05-06 09:47:17

+0

@Egi:我更新了我的問題,以源。 – Kai 2013-05-06 11:29:34

+0

您可以使用[ServiceLocator](https://commonservicelocator.codeplex.com/)來執行DI,而無需在構造函數中列出注入屬性。 – orad 2015-10-22 19:04:52

回答

3

我不明白你爲什麼需要PodcastService的組成IPodcastCommService,而不是實施IPodcastCommService,並有URL注入的字符串。我不明白你爲什麼設計不好。注入網址是好的恕我直言。

如果您想到更好的方法,我認爲它可以通過注入上下文/配置而不是原生數據類型來替代。

public class PodcastService 
{ 
    private IPodcastCommService commservice; 
    private IConnectionContext connection; 

    public PodcastService(IConnectionContext connection, IPodcastCommService commservice) 
    { 
     this.commservice = commservice; 
     this.connection= connection; 
    } 
} 

public interface IConnectionContext{ 
    string PodcastServiceUrl{get;} 
} 

但是,我再也沒有從常規方法中找到任何好處(除了你可以處理session /常量/靜態字段)。

UPDATE:

我發現similiar關於該設計不好here。總之,它不是原生類型參數(字符串等)或自定義構造函數參數是不好的。只是你需要將參數放到真正負責參數的類中。如果在抽象工廠模式中處理if-else條件,則需要自定義構造函數參數。

-3

這取決於宇正在使用的框架。例如,像DependecyResolver這樣的IoC容器的asp.net mvc提供程序集成點。您應該放置所有的邏輯來構建對象並在其中注入依賴關係。如果您正在使用aps.net,您可能會有某種預先設定的基本頁面注入依賴項。你不能在asp.net中使用構造函數注入,只能使用屬性注入。使用winforms,你可以使用某種形式的工廠來構建表單對象。

1

在您的情況,我認爲DI通過構造是完全沒有問題。爲什麼它被認爲是一個更好的辦法通過屬性去的原因是因爲它是可讀性,即想象你的構造是什麼樣子,如果你有注入20性能更好。

如果只注射幾個屬性的打算則是絕對沒有壞處做你做的事情。如果你發現你的依賴關係開始蔓延,我會考慮轉向屬性類型的方法。

+2

如果有多次注射,您可以使用'Builder'模式來簡化可讀性。我認爲這比使用屬性好得多,如果對象*需要*屬性被設置纔可以使用。 – 2013-05-06 09:02:51

+2

如果你的構造函數有20個參數,我敢打賭,你的課堂講述了SRP,並且應該被重構成更小的類,而不是濫用屬性注入以獲得更好的可讀性!在我看來,如果您需要在運行時應該能夠改變的動態行爲,屬性注入是很好的。 – Egi 2013-05-06 10:14:33

1

也許

container.RegisterType<PodcastService>(new InjectionConstructor("myUrlParameter")); 

會做的更好,不是嗎?

但如果你需要不止一個podcastservice,他們需要另一個URL,parameteroverride是確定的,我猜。