如何修复这个“循环引用”c#

时间:2011-05-02 20:00:51

标签: c# .net circular-dependency circular-reference

我有一个类库来保存我的对象:

xxxCommon \对象\ Customer.cs

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

xxxData \ DC \ CustomerDC.cs(DataComponent)

  • 此类在xxxCommon \ Objects
  • 中调用许多过程并返回对象

我现在的主要问题是循环引用,要进行“懒惰”加载我需要设置 获取电话属于xxxData \ DC中的函数,如何避免这种情况?

3 个答案:

答案 0 :(得分:3)

您可以使用回调方法解决循环引用。

例如,类ActiveRecordSQL&lt; T&gt;有一个默认的方法来创建实体,但允许它被覆盖。

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”是一个实体的子类,它位于一个不同的项目中。传递回调方法允许在现有引用上“向后”调用。

答案 1 :(得分: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(...);
    }
}

Assembly 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层,并且您将Customer数据访问对象传递给ModelFactory类的实现,以便它可以创建Customers。

答案 2 :(得分:0)

这看起来像WeakReferences的合适用法 - 您不希望随时在缓存中保留整个客户/电话列表,对吗? API documentation实际上使用大型缓存的管理作为示例。