Как исправить эту "круговую ссылку" c # - PullRequest
1 голос
/ 03 мая 2011

У меня есть библиотека классов для хранения моих объектов так:

xxxCommon \ Objects \ 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 ]

3 голосов
/ 03 мая 2011

Вы можете обходить циклические ссылки, используя методы обратного вызова.

Например, класс ActiveRecordSQL имеет метод по умолчанию для создания сущностей, но позволяет перезаписывать его.

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;
}

Класс, которому необходимо передать пользовательскую функцию, может использовать лямбда-выражение или передать ссылку на свою собственную функцию с правильной сигнатурой.

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

«GetCustomReferrer» вызывает промежуточные методы, которые просто передают методв «GetWithCustomEntity».«ReferrerFacade» подклассирует сущность и живет в другом проекте.Передача метода обратного вызова позволяет выполнять вызовы «назад» по существующей ссылке.

2 голосов
/ 03 мая 2011

Один из способов разрешения круговой зависимости - создать слой между двумя сборками:

Вместо этого сценария;

Модель сборки:

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(...);
    }
}

Интерфейсы модели сборки:

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, чтобы он мог создавать клиентов.

0 голосов
/ 03 мая 2011

Это похоже на подходящее использование для WeakReferences - вы не хотите хранить полный список клиентов / телефонов в кеше в любое время, верно?Документация API фактически использует управление большим кэшем в качестве примера.

...