Я выполняю проверку с использованием атрибутов DataAnnotation
в классах Model, а класс Model используется для проверки как на стороне клиента, так и на стороне приложения.
Моя проблема в том, что я не могу понять, как лениво загружать свойства моей Модели, не вызывая циклические ссылки
Используются следующие библиотеки:
- Сервисная библиотека WCF
- Клиентская библиотека DataAccess
- Библиотека моделей
Поскольку библиотека моделей используется как на стороне клиента, так и на стороне сервера для проверки данных, я не могу ссылаться на библиотеку DataAccess из библиотеки моделей. Следовательно, как я могу настроить отложенную загрузку?
Например, у меня есть ConsumerModel, у которого есть свойство PhoneNumbers, которое должно загружаться лениво. Как я могу загрузить PhoneNumberModels из ConsumerModel, не ссылаясь на DAL на стороне клиента?
DAL на стороне клиента:
using MyModels;
public class ConsumerDataAccess
{
public ConsumerModel GetConsumerById(int id)
{
ConsumerDTO dto = WCFService.GetConsumer(id);
return new ConsumerModel(dto);
}
}
ConsumerModel:
public class ConsumerModel
{
public ObservableCollection<PhoneNumberModel> _phoneNumbers;
public ObservableCollection<PhoneNumberModel> PhoneNumbers
{
get
{
if (_phoneNumbers == null)
{
// Can't reference DataAccess Library since that would cause a Circular Reference
}
}
}
}
Какими альтернативными способами я мог бы заставить эту архитектуру работать?
Я бы предпочел сохранить Валидацию с Моделями и использовать модели как со стороны Клиента, так и со стороны Сервера для проверки. Я также предпочел бы продолжать использовать DataAnnotation для проверки.
EDIT
Вот мое окончательное решение, основанное на ответе Лоуренса Уэнама, если кому-то интересно. Я закончил тем, что использовал делегат вместо события.
DAL:
public class ConsumerDataAccess
{
public ConsumerModel GetConsumerById(int id)
{
ConsumerDTO dto = WCFService.GetConsumer(id);
ConsumerModel rtnValue = new ConsumerModel(dto);
ConsumerModel.LazyLoadData = LazyLoadConsumerData;
return rtnValue;
}
}
private object LazyLoadConsumerData(string key, object args)
{
switch (key)
{
case "Phones":
return PhoneDataAccess.GetByConsumerId((int)args);
default:
return null;
}
}
Библиотека моделей:
public class ConsumerModel
{
public delegate object LazyLoadDataDelegate(string id, object args);
public LazyLoadDataDelegate LazyLoadData { get; set; }
public ObservableCollection<PhoneNumberModel> _phoneNumbers;
public ObservableCollection<PhoneNumberModel> PhoneNumbers
{
get
{
if (_phoneNumbers == null && LazyLoadData != null)
{
_phoneNumbers = (ObservableCollection<PhoneNumberModel>)
LazyLoadData("Phones", ConsumerId);
}
return _phoneNumbers;
}
}
}