How to fix this "circular reference" c#
i have a Class Library to hold my objects so:
xxxCommon\Objects\Customer.cs
public class Customer
{
public string url { get; set; }
public List<Telephone> telephones { get; set; }
}
xxxData\DC\CustomerDC.cs (DataComponent)
- This class call many procs and return objects in xxxCommon\Objects
My main problem now is circular reference, to make a "lazy" load i need to set the get of te开发者_开发技巧lephones atributes to a function in xxxData\DC, how can avoid this ?
You can work around circular references by using callback methods.
For example, class ActiveRecordSQL<T> has a default method for creating entities, but allows it to be overwritten.
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;
}
A class that needs to pass a custom function can use a lambda expression, or pass a reference to its own function with the right signature.
ReferrerInfo = dc.Referrers.GetCustomReferrer(referrerID, () => new ReferrerFacade()).Data as ReferrerFacade;
"GetCustomReferrer" calls intermediate methods that simply pass the method to "GetWithCustomEntity". "ReferrerFacade" subclasses an entity and lives in a different project. Passing the callback method allows calls "backward" across the existing reference.
One way you can resolve a circular dependency is to have a layer in between your two assemblies:
Rather than this scenario;
Assembly Model:
public class Customer{
//...
}
Assembly Data:
public class CustomerDAO{
public Customer LoadCustomer(int id){
return new Customer(id,...);
}
}
where the Model assembly references the Data assembly and Data can't reach back into Model to instantiate a Customer.
You can have instead;
Assembly Model:
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);
}
Assembly Data:
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);
}
}
Where both Model and Data assemblies depend on the ModelInterfaces layer and you pass the Customer Data Access Object an implementation of the ModelFactory class so that it can create Customers.
This looks like a suitable usage for WeakReferences - you don't want to hold the entire list of Customers/Telephones in cache at any time, correct? The API documentation actually uses management of a large cache as an example.
精彩评论