2013-08-29 39 views
0

我是新來的依賴注入,我試圖解決一個問題。我有兩個服務。這些服務中的每一種都有需要彼此的方法。兩個服務依賴於彼此(stackoverflow例外) - 如何解決?

例如:SiteManager有方法,它需要我的ForumManager。我的ForumManager有它需要我的SiteManager的方法。

我有以下兩類

public class SiteManager:ISiteManager 
{ 
    public IForumManager ForumManager { get; set; } 

    public SiteManager() 
    { 
     this.ForumManager = new ForumManager(); 
    } 
} 

public class ForumManager:IForumManager 
{ 
    public ISiteManager SiteManager { get; set; } 

    public ForumManager() 
    { 
     this.SiteManager = new SiteManager(); 
    } 
} 

很顯然,這將導致堆棧溢出異常,因爲他們所謂的海誓山盟。我在這裏看過很多帖子,我想我只需要一點小小的提示就可以解決這個問題。我在他們自己的程序集中有我的接口。

我想過把依賴關係放在他們自己的屬性中,所以當他們被使用時,他們就成了。不過,這是最佳做法嗎?

我沒有使用IoC容器(我之前沒有使用過)。

有關如何以「最佳實踐」方式解決此特定問題的任何提示! :-)

+0

一個「*管理器」實例化沒有參數聽起來像某些不太可能需要多個實例。使他們單身對象,並繞過這個問題完全? – Phoshi

+0

如何使用繼承有一個擁有所有常用方法的經理類? – TheKingDave

+1

這聽起來像你有一個錯位的責任。爲什麼ForumManager需要引用SiteManager?反之亦然? – MattDavey

回答

3

你不應該在你的類中調用新的,這將緊密地耦合它們。對於國際奧委會的正確模式,讓你單獨測試每個類使用嘲笑是: -

public class SiteManager:ISiteManager 
{ 
    private readonly IForumManager forumManager; 

    public SiteManager(IForumManager forumManager) 
    { 
     this.forumManager = forumManager; 
    } 
} 

public class ForumManager:IForumManager 
{ 
    private readonly ISiteManager siteManager; 

    public ForumManager(ISiteManager siteManager) 
    { 
     this.siteManager = siteManager; 
    } 
} 

但是,這並沒有解決相互遞歸。解決這個問題的最簡單的方法是不使用構造函數注入其中一個類,而是使用屬性注入,即將SiteManager放回到ForumManager上的公共屬性,並在創建這兩個對象後對其進行設置。然後

你的安裝代碼的作用: -

 IForumManager forumManager = new ForumManager(); 
    ISiteManager siteManager = new SiteManager(forumManager); 
    forumManager.SiteManager = siteManager; 

另一個替代方案是一個ForumManagerFactory通入SiteManager,例如一個Func<ISiteManager,IForumManager>

 ISiteManager siteManager = new SiteManager((s) => new ForumManager(s)); 

裏面的站點管理器,那麼你可以調用函數功能,通過this得到IForumManager。 ForumManager獲取SiteManager的一個實例,SiteManager具有ForumManager對象。

+0

我最近幾天使用了你的答案。非常感謝非常好的答案! –

0

你在做什麼和你在暗示什麼都會導致堆棧溢出異常。我不知道爲什麼你會想要做這樣的事情,你沒有給出任何提示,但我想我可以爲你創建一個經理,也許是一個單身人士,也許只是用靜態方法做:

public static void DoStuff(ISiteManager sm, IForumManager fm) 
{ 
    // your code here can use the best of both without SO 
} 

,而不是在SiteManager

+0

@downvoter請留言,以便我知道答案有什麼問題 –

+0

我沒有downvote,但我認爲這個解決方案引入了比解決問題更多的問題。也許這就是REAS爲downvote。 – MattDavey

0

你捧在ForumManagerISiteManagerIForumManager顯然不能有interdependant類。什麼,你需要做的是創建一個單獨的類,並搬到那裏使用相同的時間論壇經理和sitemanger方法:下面是一個示例3類:

class ForumAndSiteManager 
{ 
    public ForumAndSiteManager(ISiteManager siteMaanger, IForumManager forumManager) 
    { 
     //save the injected object to private fileds 
    } 

    //define methods which will use both sitemanager and forum manager 
} 

這樣,您將剎車圓depedency

+0

你*可以*具有相互依賴的類。 –

+0

很顯然我的意思是相互依賴的類,它們在constrcutors中相互呼叫,因爲問題顯示爲 –

0

將MVP與winforms和AutoFac結合使用時,對於引用展示者和參與視圖的演示者的視圖,我遇到了完全相同的問題。我解決它的方法是使用Initialize方法將其中一個類傳遞給另一個類。我不知道這是否是最好的做法,但我已經看到它之前(this question about mvp

因此,對於實施細節提示:

public class SiteManager:ISiteManager 
{ 
    public IForumManager ForumManager { get; set; } 

    public SiteManager() 
    { 

    } 

    public Initialize(IForumManager forumManager) 
    { 
     ForumManager = forumManager 
    } 
} 

public class ForumManager:IForumManager 
{ 
    public ISiteManager SiteManager { get; set; } 

    public ForumManager(ISiteManager siteManager) 
    { 
     this.SiteManager = new SiteManager(); 
     this.SiteManager.Initialize(this); 
    } 
} 

編輯實際上可能會與發佈其他的解決方案去,我只是單純地從循環依賴的角度看待這個問題

0

您絕對應該避免循環依賴關係。我的意思是A取決於A和B上的B.

這就像你的context依賴關係的癌症。我們使用spring.net框架,與java的版本相反,如果它發現了這種依賴關係,則無法切換失敗的系統。我不得不說,這給我們帶來了只有混亂和春天的日誌搜索和分析小時。

我們幾乎定義了200個沒有任何問題,但是一旦我們添加只是另一個豆以及Lazy引用它失敗。這幾乎是不可能的,以解決我們的解決方案,以避免它,所以我們掛鉤和掛鉤,而它失敗:-(