2013-07-25 91 views
2

基於這個問題的答案:Cyclic dependency with ninject和這個問題:Ninject: give the parent instance to a child being resolved這兩個都說你可以使用雙向屬性注入來解決循環依賴關係,只要你改變了範圍不作爲默認的瞬態範圍。所以我試着這樣做,我有UserServiceGroupService需要對方(請不要說改班或使用第三課等!)。我有一個使用ninject像這樣的通用EntityServiceFactoryNinject,使用雙向屬性注入來解決循環依賴

public static class EntityServiceFactory 
{ 
    public static TServiceClass GetService<TServiceClass>() 
     where TServiceClass : class 
    { 
    IKernel kernel = new StandardKernel(); 
    return kernel.Get<TServiceClass>(); 
    } 
} 

我的服務:

public class GroupService : EntityService<GroupRepository, Group, DbContext> 
{ 
    public UserService _userService { private get; set; } 


    public GroupService(GroupRepository repository, UserService userService) : base(repository) 
    { 
     userService._groupService = this; 
    } 

public class UserService : EntityService<UserRepository, User, DbContext> 
{ 
    public GroupService _groupService { private get; set; } 

    public UserService(UserRepository repository, GroupService groupService) 
     : base(repository) 
    { 
     groupService._userService = this; 
    } 

然後按在回答這些問題的說明以下內容添加到我的EntityServiceFactory

kernel.Bind<GroupService>().ToSelf().InCallScope(); 
kernel.Bind<UserService>().ToSelf().InCallScope(); 

但我仍然得到錯誤:

A cyclical dependency was detected between the constructors of two services.

我是否正確地進行了兩種屬性注入?我該如何解決這個問題?

+0

我不知道答案,但這是一個很好的問題。 +1。 – n00b

+1

我知道你堅持要我們不要嘮叨你的設計,但你能否解釋爲什麼這兩項服務需要相互依賴? – Steven

+0

btw。你的'EntityServiceFactory'的用法就像Service Locator反模式一樣。您可能想閱讀[本文](http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/)以驗證在您的應用程序中使用此模式是否有問題。 – Steven

回答

2

韋爾普,事實證明,我不明白我鏈接的問題的答案。我根本沒有做任何類似於屬性注入的事情,我最終做的是這樣的:

任何時候都有一個循環依賴項,我會從構造函數中刪除一個循環誘導服務,並將其替換爲:

private UserService _userService; 
    private UserService UserService 
    { 
     get { return _userService ?? (_userService = EntityServiceFactory.GetService<UserService>()); } 
    } 

這實際上最終與屬性注入非常接近(http://ninject.codeplex.com/wikipage?title=Injection%20Patterns)。它並不像構造函數注入那樣優化,但仍然不是一個糟糕的解決方案。我也可以這樣做(實際屬性注入):

private UserService _userService; 
    [Inject] 
    private UserService UserService 
    { 
     get { return _userService; } 
     set { _userService = value; } 
    } 

我只是選擇了自己的路,因爲它並不需要我的服務有情況下,我是否會改變的是我的用法ninject特定的代碼,而是叫EntityServiceFactory.GetService是基本上和[Inject]屬性做同樣的事情。