2016-02-24 2 views
2

Я работаю над решением Xamarin.Forms, которое использует библиотеку PCL для обмена кодами между моими проектами Android и iOS. Это было здорово, поскольку большинство пользовательских интерфейсов и логический код можно хранить в одном месте. Конечно, есть некоторые классы платформы, которые я создал и связал с PCL, используя DependencyService, и это нормально для большинства классов, поскольку код значительно отличается между платформами (макет/внешний вид интерфейса), например.Как уменьшить количество дубликатов кода между моими проектами на платформе?

Однако существует одно подмножество классов, которое использует различные пространства имен, которые недоступны для проектов PCL (в частности, пространства имен System.Data). Чтобы обойти это ограничение, мне пришлось написать DependencyService для каждого из этих классов. Меня беспокоит, что код между Android и iOS точно такой же, минус одна или две строки. Код довольно сложный, и я не хочу забывать обновлять его дважды, когда возникнет такая необходимость.

Есть ли способ уменьшить объем кода, дублированного между этими двумя проектами, учитывая, что я не могу поместить код в PCL из-за необходимых пространств имен, которые недоступны?

+1

Я использую 'приманку и switch' метод (http://log.paulbetts.org/the-bait-and-switch-pcl-trick/) НО использовать одни и те же файлы кода на платформе -специфические сборки, создавая два проекта для конкретной платформы, включая/связывая эти файлы кода в каждом проекте с помощью совместно используемого проекта, а затем использовать директивы компилятора платформы для нескольких строк кода, которые меняются между платформами ... Поэтому, смешивая PCL-стиль код с директивами платформы вы можете пропустить дублированный код PCL * требуется * ... – SushiHangover

+1

(продолжение) ... Если у вас действительно большие определения интерфейса или быстро меняющиеся, чтобы сэкономить время на обновление фиктивных подписи PCL, я использовать шаблоны T4 для определения и генерации интерфейсов и отдельных классов, специфичных для платформы ... – SushiHangover

+0

@SushiHangover хороший трюк. Будет придерживаться этого рукава :) – matthewrdev

ответ

0

Мне удалось устранить весь дублированный код, используя общий проект (как предложил @matthewrdev). Процесс был немного сложнее, чем я ожидал, поэтому я добавлю руководство по тому, что я сделал.

  1. Создайте новый совместный проект Xamarin.Forms. (К сожалению, у меня была возможность создать проект «пустой проект» (совместно используемый), в который вошли предварительно созданные проекты для Android и iOS. Я удалил их, поскольку у меня уже были необходимые проекты для платформы.)

  2. Добавить весь дублированный код для общего проекта. Возможно, вам потребуется обновить пространства имен. Для любого кода, который необходимо выполнить для конкретной платформы, вам нужно будет использовать директивы препроцессора #if __ANDROID__ или #if __IOS__.

  3. Добавить ссылку на общий проект в своих проектных проектах (в моем случае, Android и iOS). В VS2013 это было немного сложно, так как вы (по-видимому) не смогли добавить ссылки на совместные проекты. Вам необходимо либо вручную изменить файл .csproj (см. this answer), либо вы можете использовать расширение Shared Project Reference Manager для VS2013.

  4. Обязательно добавьте условные символы компиляции __ANDROID__ и __IOS__ в свои проекты платформы. Для этого вам нужно открыть свойства проекта, перейдите на вкладку «Создать» и добавьте символ, в котором говорится «условные символы компиляции».

Эти инструкции предназначены для Visual Studio 2013, но этапы аналогичны для Xamarin Studio и, вероятно, VS2015.

1

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

Я использовал этот шаблон раньше для доступа SQlite. У меня была потребность в поддержке ADO.net на низком уровне, что означает ручное отображение данных из SqliteDataReader. Логика для этого распространена между платформами, но не может идти в PCL. Таким образом, у меня есть SharedProject для сопоставления данных, и в реализациях моей платформы Platform ссылка на этот проект.

См. Ниже пример диаграммы классов.

enter image description here

Смежные вопросы