2. Обо мне
На данный момент руковожу разработкой мобильных
приложений агентства Actis Wunderman, в котором тружусь с
момента появления на свет агентства Actis, позже
присоединившегося к сети Wunderman.
Ранее занимался разработкой, созданием и внедрением
интернет-проектов.
3. Наши работы
Мы занимаемся разработкой приложений для ведущих
платформ около трех лет. Вот, что мы сделали для Windows
Phone:
•КиноПоиск
•Concert.ru
•ЛитРес
Несколько неназываемых проектов скоро должны быть
опубликованы, тогда мы их назовём.
7. Мы – ленивые
И поэтому создали несколько инструментов, которые
позволяют нам экономить время и усилия:
•Фреймворк работы с сущностями и коллекциями
•Фреймворк моделей представлений
•Фреймворк представлений для Windows Phone и других
платформ
•T4-генераторы кода
Кроме того, сервер непрерывной интеграции и тесты
позволяют нам не заботиться о проблемах внесения
изменений в код и координировать совместную работу
8. Данные
Сценарии использования источников данных в мобильных
приложениях, в порядке уменьшения частоты использования:
•Получить коллекцию заголовков данных
•Получить конкретную сущность
•Выполнить единичное действие с источником данных
•Отправить изменённую сущность
«Мобильность» платформы накладывает некоторые
ограничения на возможность и целесообразность передачи
больших объёмов данных
9. Данные
Данные можно разделить на две категории – сущности и
коллекции сущностей
И сущности и коллекции сущностей бывают
идентифицируемые и неидентифицируемые
11. Коллекции
Интеллектуальное обновление:
XCollection<T>
Применение фильтров:
XFilteredCollection<T>
Объединение и разделение:
XCombinedCollection<T>, XSubRangeCollection<T>
13. Пример: Свойства
class Person : XObject
{
string _name;
XCollection<Person> _children;
public string Name
{
get { return _name; }
set { SetProperty( ref _name, value, “Name” ); }
}
public XCollection<Person> Children
{
get { return _children; }
set { SetProperty( ref _name, value, “Children” ); }
}
}
15. Пример: Клонирование
Person person = new Person
{
Name = “John”,
Children = new XCollection<Person>
{
new Person { Name = “Bob” }
}
};
Person softClone = (Person) person.Clone( false );
Person deepClone = (Person) person.Clone( true );
person.Children[0].Name = “Mary”;
softClone.Children[0].Name // “Mary”
deepClone.Children[0].Name // “Bob”
16. Пример: Обновление
Person person1 = new Person { Name = “John” }
Person person2 = new Person { Name = “Mary” }
person1.Update( person2 );
person1.Name // “Mary”
XCollection<Person> l1 = new XCollection<Person>() { … };
XCollection<Person> l2 = new XCollection<Person>() { … };
var result = l1.Update( l2 );
17. Пример: Коллекции
XCollection<Person> l1 = new XCollection<Person>() { … };
XCollection<Person> l2 = new XCollection<Person>() { … };
var softClone = l1.Clone( false );
var deepClone = l1.Clone( true );
var result = l1.Update( l2 );
18. Пример: Хитрые коллекции
XCollection<Person> studentsOfClassA = …;
XCollection<Person> studentsOfClassB = …;
var firstThreeStudentsOfClassA =
new XSubRangeCollection( studentsOfClassA, 0, 3 );
var firstTwoStudentsOfClassB =
new XSubRangeCollection( studentsOfClassB, 0, 2 );
var topStudents =
new XCombinedCollection(
firstThreeStudentsOfClassA,
firstTwoStudentsOfClassB );
20. Демонстрация
Сгенерированные классы, содержащие ключевые элементы,
необходимые для эффективной работы с данными:
•Правильное обновление данных
•Правильное клонирование данных
•Выборка с помощью ключей в коллекциях и кэше
21. Модели представлений
Предназначены для получения и преобразования данных,
необходимых представлениям, а также для выполнения
других действий над этими данными.
Наиболее частые операции в мобильных приложениях –
загрузка данных (списки или отдельные сущности) для
представления их пользователю.
Работа с источниками данных должна быть асинхронной –
нельзя блокировать поток пользовательского интерфейса.
Необходимо учитывать возможность досрочного прекращения
выполняемых операций – по разным причинам.
22. Сессии
Всё «управляемое» общение модели (модели представления)
с внешним миром происходит в рамках сессии
Сессия содержит параметры, необходимые для доступа к
данным
Сессия содержит жетон, используемый для прекращения
асинхронных задач (CancellationToken)
Обработкой сессии занимается модель
23. Работа с сессией
Создание
var session = CreateSession()
.AddParameter( “userName”, “John” )
.AddParameter( “age”, 48 );
Доступ к параметрам
var userName = session.Parameters.Get<string>( “userName” );
var age = session.Parameters.Get<int>( “age” );
var sex = session.Parameters.Get<string>( “sex”, “male” );
Обработка
await viewModel.Load( session );
24. Откуда она знает, что делать?
Виртуальные методы
ShouldLoadSession
LoadSession
Части
RegisterPart
string part,
Func<Session, Task> processor,
Func<Session, bool> checker,
bool loadIfNoPartsSpecified
25. Типичная модель
Конструктор
Получает сервисы через DI
Регистрирует части
Создает команды
Методы обработки частей
Проверяют необходимость обработки сессии
Осуществляют доступ/обновление данных
26. Модель сущности
Использует расширенную сессию, которая включает в себя
ключ, идентифицирующий объект: EntitySession
Регистрирует методы для части, связанной с обработкой
сущности: ShouldLoadEntity и LoadEntity.
Объявляет свойство Entity
27. Типичная модель сущности
Конструктор
Получает сервисы
Создает команды
Метод LoadEntity
Загружает данные из внешнего источника или из кэша
Присваивает значение свойству Entity
28. INavigationService
Один из самых важных сервисов, доступных моделям
Определяет независимый от платформы способ навигации
между видами
ns.Navigate( “PersonView”, Parameters.Create( “Id”, 1 ) );
Позволяет создавать и использовать команды навигации:
ViewDetails = new NavigationCommand(
ns,
“DetailedView” );
PersonSelected = new NavigationCommand<Person>(
ns,
“PersonView”,
person => person.KeyParameter() );
29. Другие сервисы
IDataExchangeService
Информирование об обмене данными
IViewModelExceptionHandlingService
IExceptionHandlingService
Унифицированная обработка исключений
31. Page
Управление жизненным циклом
OnPageCreated, OnPageDestroyed,
OnPageAsleep, OnPageAwaken, OnPageResurrected
Доступ к параметрам
ViewParameters
Контекст для связывания данных
CreateDataContext
Атрибутирование для навигации
[View( “UserView” )]
[ViewParameter( “userName”, typeof( string ) )]
32. ViewModelPage<TViewModel>
Страница с созданной моделью
Начальная загрузка данных
CreateDataSession, CreateDataSessionAsync
OnDataLoadComplete, OnDataLoadFailed
Обработка нештатных ситуаций (FAS)
Управление областью жизни модели
Связывание данных в XAML
<TextBlock Text=“{Binding ViewModel.Title}”/>
34. Но это еще не всё!
Генератор классов-заглушек и частичных классов-
представлений:
<View Name=“MainView”/>
<View Name=“FeedChannelView” Entity=“FeedChannel”/>
Во многих случаях файл View.xaml.cs не нужен, всё делается
автомагически
Генератор константных имен представлений и параметров, а
также методов для создания параметров навигации
35. Но и это еще не всё!
Декораторы страниц используются для выполнения
однообразных действий со страницами, например для показа
сообщений об ошибках, исчезновении сетевого подключения и
т.п.
Встроенный механизм обработки страниц, для которых нужна
аутентификация – параметр RequiresAuthentication
атрибута [View()]