Как исправить эту циклическую ссылку c #

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

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, как этого избежать?


person waldecir    schedule 02.05.2011    source источник


Ответы (3)


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

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

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

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

person Grokodile    schedule 02.05.2011

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

Например, класс 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;
}

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

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

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

person Cylon Cat    schedule 02.05.2011
comment
Это хороший способ, если вы столкнулись со сложной задачей разрешения циклической зависимости, но не следует ли в первую очередь, чтобы хороший дизайн устранял такую ​​зависимость. - person Shamim Hafiz; 03.05.2011
comment
Все конструкции - это компромиссы, и в любой сложной системе вы найдете области, где вам потребуется двусторонняя связь между компонентами. Функциональное программирование предлагает ряд инструментов, таких как обратные вызовы, продолжения и закрытия. Еще одно универсальное и распространенное решение проблемы - обработчики событий; нижний уровень предоставляет обработчик событий и вызывает события, а верхний уровень регистрирует обработчик событий для получения уведомлений. (См. Отличный пример INotifyPropertyChanged в .NET.) Внедрение зависимостей предлагает другой подход к решению проблем с зависимостями. - person Cylon Cat; 03.05.2011

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

person Steve Townsend    schedule 02.05.2011