2011-05-02 59 views
1

我有一個類庫來握住我的對象,所以:如何解決這個 「循環引用」 C#

xxxCommon \對象\ Customer.cs

public class Customer 
    { 
     public string url { get; set; } 
     public List<Telephone> telephones { get; set; } 
    } 

xxxData \ DC \ CustomerDC.cs(DataComponent )在xxxCommon \

  • 這個類調用許多特效和返回對象的對象

我現在的主要問題是循環引用,爲了使一個「懶惰」的負載我需要設置電話的屬性到xxxData \ DC中的一個函數,怎麼能避免這種情況呢?

回答

2

一種方法是在你的兩個組件之間的層:

不是這種情況相反;

裝配模型:

public class Customer{ 
    //... 
} 

大會數據:

public class CustomerDAO{ 
    public Customer LoadCustomer(int id){ 
     return new Customer(id,...); 
    } 
} 

在機型集的引用數據彙編和數據不能達到回模型實例化一個客戶。

你可以改爲;

裝配模型:

public class CustomerModel:Customer{} 
public class ModelFactoryImp:ModelFactory{ 
    public Customer CreateCustomer(int id,//...customer params){ 
     return new CustomerModel(...); 
    } 
} 

大會ModelInterfaces:

public abstract class Customer{//...} 
public abstract ModelFactory{ 
    Customer CreateCustomer(int id,//...customer params); 
} 

大會數據:

public class CustomerDAO{ 
    private ModelFactory _modelFactory; 

    public CustomerDAO(ModelFactory modelFactory){ 
     _modelFactory = modelFactory; 
    } 

    public Customer LoadCustomer(int id) 
    { 
     // Data Access Code 
     return _modelFactory.CreateCustomer(id,//...cutomer params); 
    } 
} 

如果雙方模型和數據組件依賴於ModelInterfaces層上和你通過客戶數據訪問對象ModelFactory類的實現,以便i t可以創建客戶。

0

這看起來很適合用於WeakReferences - 您不希望隨時將客戶/電話的整個列表保存在緩存中,對嗎?例如,API documentation實際上使用大型緩存的管理。您可以解決循環依賴

3

您可以使用回調方法解決循環引用問題。

例如,類ActiveRecordSQL <T>有一個創建實體的默認方法,但允許它被覆蓋。

private Func<T> GetNewEntity; 

protected ActiveRecordSQL() // constructor 
{ 
    GetNewEntity = DefaultGetNewEntity; 
} 

protected Result<T> GetWithCustomEntity(SqlCommand cmd, Func<T> GetCustomEntity) 
{ 
    GetNewEntity = GetCustomEntity; 
    return Get(cmd); 
} 

private T DefaultGetNewEntity() 
{ 
    return new T(); 
} 

protected T Populate(DataRow row, T existing) 
{ 
    T entity = existing ?? GetNewEntity(); 
    entity.Populate(row); 
    return entity; 
} 

需要傳遞自定義功能可以使用lambda表達式,或傳遞到參考其自身的功能與正確的簽名的類。

 ReferrerInfo = dc.Referrers.GetCustomReferrer(referrerID,() => new ReferrerFacade()).Data as ReferrerFacade; 

「GetCustomReferrer」 調用中間方法,簡單地傳遞該方法爲 「GetWithCustomEntity」。「ReferrerFacade」是一個實體的子類,並且生活在一個不同的項目中。傳遞迴調方法允許在現有引用中調用「向後」。

+0

如果您面臨解決循環依賴的困難任務,這是一個好方法,但不應該是一個好的設計首先消除這種依賴。 – 2011-05-03 06:15:29

+1

所有設計都是妥協,在任何複雜系統中,您都會發現需要組件之間進行雙向通信的區域。函數式編程提供了許多工具,例如回調,延續和閉包。這個問題的另一個多功能和通用的解決方案是事件處理程序;下層提供事件處理程序並引發事件,而上層則註冊事件處理程序以接收通知。 (在.NET中查看INotifyPropertyChanged是一個很好的例子。)依賴注入爲解決依賴性問題提供了另一種方法。 – 2011-05-03 11:18:35