2011-05-02 86 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