Я борюсь с некоторыми базовыми принципами проектирования MVVM в приложении Silverlight 4 с использованием служб и объектов RIA. Вот основной сценарий, который работает нормально:
DataViewModel.cs
public DataViewModel : NotificationObject
private DataDomainContext _dataContext;
public DataViewModel()
{
_dataContext = new DataDomainContext();
if (!DesignerProperties.IsInDesignTool)
{
Data = _dataContext.Data;
dataContext.Load(_dataContext.GetDataQuery(), null, null);
}
}
private IEnumerable<DataEntity> _data;
public IEnumerable<DataEntity> Data // INPC property
{
get { return _data; }
set
{
if (value != _data)
{
_data = value;
PropertyChanged(this, new PropertyChangedEventArgs("Data"));
}
}
}
}
DataGrid, на мой взгляд, связан в одностороннем порядке с DataViewModel.Data, а DataDomainContext - это контекст домена RIA, предоставляемый после компиляции доменной службы для объекта DataEntity.
Я хочу отделить модель вида от DAL. Мне нужен класс DataService, который позаботится о том, чтобы запрашивать данные в контексте домена:
public DataViewModel : NotificationObject
private DataService _dataService;
public DataViewModel(DataService dataService)
{
_dataService = dataService;
if (!DesignerProperties.IsInDesignTool)
{
Data = _dataService.Data;
_dataService.GetData();
}
}
...
}
Тем не менее, я не могу понять это правильно. Это легко сделать? Я не проектировал службу данных с обратными вызовами раньше. Я попытался связать свойства данных через INPC между тремя классами, но DataGrid в пользовательском интерфейсе был пустым. Я также хотел бы преобразовать в коллекцию нового типа, DataDto, чтобы мой уровень представления не был связан с бэкэндом. Я попытался что-то подобное без удачи:
DataService.cs
public DataService : INotifyPropertyChanged
{
public DataService()
{
_dataContext = new DataDomainContext();
}
public event PropertyChangedEventHandler PropertyChanged;
public void GetData()
{
DataEntities = _domainContext.Data;
_dataContext.Load(_dataContext.GetDataQuery(), FinishedLoading, null);
}
private void FinishedLoading(...)
{
Data = DataEntities.Select(de => new DataDto(de));
}
public IEnumerable<DataDto> Data { ... } // INPC property, used for binding in ViewModel
public IEnumerable<DataEntity> DataEntities { ... } // INPC property
...
}
Я даже на правильном пути здесь? Я что-то упускаю из-за высокого уровня или у меня просто нет деталей?
Edit:
Я смог со временем разобраться. Ответ включает передачу обратного вызова в вызов службы данных / хранилища через действие <>. Тип возврата вызова на самом деле void, и для доставки результатов используются аргументы событий. Я рад опубликовать рабочий код, если кому-то интересно, просто оставьте заявку в комментариях.