Статьи

Введение в Xamarin. Формы и обмен сообщениями

С тех пор, как Xamarin 3 был представлен, вокруг него было довольно много шума. Идея создания мобильного приложения, включая пользовательский интерфейс, с использованием единой кодовой базы, поразительна. Но Xamarin.Forms это гораздо больше, чем это. Одной из часто упускаемых функций, включенных в Xamarin.Forms, является концепция обмена сообщениями, и это тема этого руководства.

Если у вас есть опыт написания программного обеспечения в корпоративных средах, вы также можете иметь опыт или хотя бы слышать об обмене сообщениями в своих приложениях. Обмен сообщениями — это термин, используемый для описания приложений, использующих преимущества шаблона публикации / подписки (pub / sub). Архитектура публикации / подписки состоит из трех основных игроков:

  • Сообщения
  • издатели
  • абоненты

Основное внимание в этом процессе уделяется сообщениям. Сообщения — это просто способ передачи информации о произошедшем событии . Это событие обычно связано с каким-либо бизнес-процессом и содержит информацию, необходимую для систем, которые в конечном итоге используют эти данные для выполнения какой-либо другой операции.

Два других игрока, издатели и подписчики, являются поставщиками этих сообщений. Как видно из названий, издатели являются отправителями сообщений, а подписчики — получателями сообщений.

Основной процесс обмена сообщениями довольно прост. Внутри системы происходит определенное событие. Это событие может быть чем-то простым, например, пользователь нажимает кнопку, или таким сложным, как бизнес-правило, запускаемое в торговом приложении крупной финансовой фирмы. В мире обмена сообщениями между этими двумя вещами есть небольшая разница. Все, что вам нужно знать, это то, что что-то случилось.

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

На другом конце уравнения находятся подписчики. Подписчики — полная противоположность издателям. Они ждут публикации сообщений определенного типа. Отсюда и их имя, они подписаны на определенные типы событий. Когда подписчик видит, что произошло событие, на которое он подписан, он получает это сообщение и все его данные и что-то с ним делает. Как только этот процесс завершен, подписчик возвращается к ожиданию большего количества сообщений.

Имея в виду эту архитектуру, вы можете задаться вопросом, почему или когда вы должны ее использовать. Обычно разработчики предпочитают использовать этот тип архитектуры по двум причинам: слабая связь и масштабируемость.

С точки зрения разработки программного обеспечения, слабая связь — это концепция разделения различных компонентов в вашем приложении настолько, насколько это возможно, настолько, чтобы они знали как можно меньше друг о друге. Такое разделение позволяет разработчикам сосредоточиться больше на функциональности системы и меньше на взаимодействии различных компонентов или частей системы. Это позволяет легче изменять функциональность и тестировать различные компоненты.

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

Теперь давайте посмотрим, как мы можем использовать эту чрезвычайно мощную архитектуру для использования в наших мобильных приложениях с использованием Xamarin .

Вступление в мир обмена сообщениями в Xamarin.Forms на самом деле довольно просто сейчас, когда мы понимаем основные концепции обмена сообщениями. Все, что нам сейчас нужно, — это конструкция для доступа к ним. К счастью для нас, есть только один класс, о котором нам действительно нужно беспокоиться, это MessagingCenter . Класс MessagingCenter является частью Xamarin.Forms и имеет методы, помогающие нам как в публикации, так и подписке на сообщения. Давайте посмотрим на каждого.

Первый метод, который мы рассмотрим в классе MessagingCenter — это Send . Хотя концепция в контексте обмена сообщениями является общедоступной, реализация Xamarin.Forms использует Send . Существует две версии метода Send которые можно использовать для публикации данных.

  • MessagingCenter.Send<TSender>(TSender sender, string message)
  • MessagingCenter.Send<TSender, TArgs>(TSender sender, string message, TArgs args)

Оба эти варианта являются общими. Первый позволяет вам указать отправителя этого сообщения, а второй — также дополнительный аргумент, тип полезной нагрузки.

Важно отметить, что универсальный параметр TArgs может быть любого типа. Это может быть что-то простое, например string или такое же сложное, как пользовательский тип.

Теперь, когда мы понимаем, как публиковать или Send сообщения в систему, пришло время подписаться на них. Для этого мы будем использовать метод Subscribe в классе MessagingCenter .

Подобно двум версиям метода Send метод Subscribe также имеет две перегрузки.

  • MessagingCenter.Subscribe<TSender>(object subscriber, string message, Action<TSender> callback, TSender sender = null)
  • MessagingCenter.Subscribe<TSender, TArgs>(object subscriber, string message, Action<TSender, TArgs> callback, TSender sender = null)

Для методов Subscribe мы указываем, кто является подписчиком. Обычно мы будем указывать this для первого параметра. Второй параметр будет содержать то же имя сообщения, которое было указано в методе Send поэтому мы можем получать уведомления, когда это конкретное сообщение было отправлено. Третий параметр — это общий делегат, который принимает отправителя и, возможно, аргументы, в зависимости от того, какая версия метода используется. Делегат — это обратный вызов, который выполняется при публикации сообщения этого типа. Наконец, это обнуляемый параметр, определяющий, на какого TSender должно быть подписано это сообщение. Можно принять как null чтобы принять этот тип сообщения от любого отправителя.

Отлично, теперь мы подписываемся на сообщения, но что, если мы больше не заботимся об определенных сообщениях? Хороший вопрос. Есть еще один способ принять во внимание.

Часто пропускаемый процесс в мире обмена сообщениями отписывается. Когда вы работаете в очень крупной инфраструктуре корпоративного класса, возможно, это не так важно. Напротив, когда вы работаете в небольшой среде, например, в телефоне, это становится более важным.

Хотя использование архитектуры обмена сообщениями обеспечивает большую гибкость и масштабируемость, оно по-прежнему требует системных ресурсов. Из-за этого мы не можем продолжать увеличивать количество подписчиков в системе бесконечно. В таком случае мы должны уважать ресурсы как можно лучше. В Xamarin.Forms мы делаем это путем вызова метода Unsubscribe. Этот метод позволяет нам сказать, что мы больше не заботимся о публикации определенного сообщения в системе.

Метод Unsubscribe также имеет две перегрузки.

  • MessagingCenter.Unsubscribe<TSender>(object subscriber, string message)
  • MessagingCenter.Unsubscribe<TSender, TArgs>(object subscriber, string message)

Вы можете заметить, что универсальные аргументы не проявляются в списке параметров. Только разработчики имеют хорошее представление о том, почему именно, но я чувствую, что это скорее формальность. В любом случае, я хочу быть последовательным во всех своих вызовах « Send , « Subscribe и « Unsubscribe , и использую одни и те же подписи и аргументы, чтобы избежать путаницы.

Теперь, когда мы понимаем основные концепции обмена сообщениями, пришло время создать простой пример, использующий эти идеи.

В этом примере мы создадим простое приложение Xamarin.Forms, которое будет использовать все три метода класса MessagingCenter упомянутые ранее в этой статье. Само приложение может показаться несущественным, но оно предоставит полезную иллюстрацию того, как использовать эти концепции в ваших приложениях в будущем.

Мы начнем с создания нового приложения Xamarin.Forms. Для этого просто откройте Xamarin Studio (или Visual Studio) и выберите « Файл»> «Новое решение» . В диалоговом окне « Новое решение » выберите семейство шаблонов мобильных приложений и выберите один из шаблонов. Я выберу версию PCL , но вы можете использовать версию Shared Project, если хотите.

Как только решение будет создано, давайте добавим немного кода. В общем проекте создайте новый класс и назовите его MainPage . Это будет экран в приложении, который будет содержать как пользовательский интерфейс, так и логику. Это, очевидно, можно разбить на более логичные части, но это приложение достаточно простое, и я не думаю, что это было необходимо.

Замените содержимое файла MainPage.cs следующим:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using Xamarin.Forms;
using System.Collections.Generic;
using System.Collections.ObjectModel;
 
namespace MessagingSample
{
    public class MainPage : ContentPage
    {
        private List<string> _eventTimes;
        private bool _isSubscribed = false;
        private ListView _eventList;
 
        public MainPage ()
        {
            _eventTimes = new List<string> ();
 
            var clearButton = new Button {
                Text = «Clear»
            };
 
            clearButton.Clicked += (sender, e) => {
                _eventTimes.Clear();
                UpdateList();
            };
 
            var publishButton = new Button {
                Text = «Publish»
            };
 
            publishButton.Clicked += (sender, e) => {
                MessagingCenter.Send<MainPage, DateTime>(this, «boom», DateTime.Now);
            };
 
            var subUnsubButton = new Button {
                Text = «Subscribe»
            };
 
            subUnsubButton.Clicked += (sender, e) => {
                _isSubscribed = !_isSubscribed;
 
                if(_isSubscribed) {
                    subUnsubButton.Text = «Unsubscribe»;
                    MessagingCenter.Subscribe<MainPage, DateTime>(this, «boom», (page, time) => {
                        _eventTimes.Add(time.ToString());
                        UpdateList();
                    });
                }else {
                    subUnsubButton.Text = «Subscribe»;
                    MessagingCenter.Unsubscribe<MainPage, DateTime>(this, «boom»);
                }
            };
 
            var buttonStack = new StackLayout {
                Spacing = 20,
                Padding = 20,
                Orientation = StackOrientation.Horizontal,
                Children = { publishButton, subUnsubButton, clearButton },
                HorizontalOptions = LayoutOptions.CenterAndExpand
            };
 
            _eventList = new ListView {
                ItemsSource = new ObservableCollection<string>(_eventTimes)
            };
 
            var mainStackLayout = new StackLayout {
                Children = { buttonStack, _eventList },
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand
            };
 
            Content = mainStackLayout;
        }
 
        private void UpdateList() {
            _eventList.ItemsSource = new ObservableCollection<string> (_eventTimes);
        }
    }
}

Поначалу это может показаться немного ошеломляющим, но, уверяю вас, это довольно просто. Есть три кнопки:

  • Опубликовать: использует метод Send для публикации сообщения с именем boom
  • Подписаться / отписаться : переворачивает страницу с подписки / отписки от boom
  • Очистить: очищает содержимое ListView

Основная предпосылка этого приложения заключается в том, что оно запускается в неподписанном состоянии. В этом состоянии, если вы нажмете кнопку « Опубликовать» , похоже, ничего не произойдет. Мы знаем, что сообщение о boom публикуется, но, поскольку подписчиков нет, ничего не происходит.

После того, как вы нажмете кнопку « Подписаться» , приложение перейдет в подписанное состояние, в котором оно теперь boom сообщения о boom . Получив это сообщение, он помещает новое значение DateTime в коллекцию _eventTimes , которая обновляется в ListView _eventList помощью ObservableCollection .

Остальная часть кода — это просто базовое форматирование и интервал.

Запуск приложения в iOS Simulator должен выглядеть примерно так:

Аналогично, начальное состояние в эмуляторе Android должно выглядеть следующим образом:

После нажатия кнопки « Подписаться» и публикации нескольких сообщений вы должны увидеть обновление пользовательского интерфейса, получив некоторые значения DateTime в ListView .

Там у вас есть это. Вы успешно создали приложение Xamarin.Forms, которое использует архитектуру, обычно предназначенную для крупных предприятий. В этот момент вы должны быть весьма взволнованы, поскольку теперь у вас есть новый инструмент в наборе инструментов, который позволит вам создавать очень масштабируемые и гибкие, не говоря уже о тестируемых, приложения, которые могут работать в руках конечного пользователя. И это может открыть дверь для многих других возможностей.