[Из песочницы] Портирование большого проекта на .NET Core

Дано: система с 10-летней историей, разработанная на C#, с довольно большой кодовой базой. Серверной частью системы является веб-сервис (хостится в IIS, протокол SOAP), активно работающий с базой данных, с кэшированием в Redis, с различными проверками безопасности, поиск в Elasticsearch.

Задача: обеспечить работу системы на Linux без потери в производительности с минимальными телодвижениями.

Напрашиваются 3 варианта решения задачи:

  1. Использовать Mono
  2. Использовать .NET Core
  3. Переписать все на Java\Go\Python

3-й вариант отбрасывается сразу же, на переписывание уйдет несколько человеко-лет разработки. Остаются Mono и .NET Core.

Что не так с Mono


Хоть и технология появилась давно и успешно используется (например, в Xamarin) есть несколько сомнений насчет дальнейшего развития Mono:
  • Приобретение Xamarin Microsoft’ом. Microsoft публично делает ставку на .NET Core и вкладывает в него деньги. Процесс разработки .NET Core открыт, доступны даты релизов, roadmap и т.д. Что будет с Mono вне Xamarin вопрос. Будет ли Microsoft одновременно развивать 2 конкурирующие реализации .NET?
  • Отсутствие фидбека. С какой производительностью работает Mono? Можно ли применять в enterprise? Про Mono почти не говорят на конференциях, такое чувство, что технологию никто не использует

В итоге выбор пал на .NET Core. Задача усложняется, что нужно одновременно поддерживать и .NET 4.6.1 реализацию, и .NET Core в одной кодовой базе, так как не всех клиентов можно обновить и нужна обратная совместимость.

Миграция проектных файлов


Для начала нужно установить Update 3 для Visual Studio 2015 и свежий .NET Core SDK (свежие билды публикуются на странице проекта). Затем для каждого csproj-файла нужно создать его аналог — project.json. Заходим в папку с каждый проектом, в командной строке вводим dotnet new.

Появится project.json, из него нужно удалить строку про emitEntryPoint, если сборка не содержит метода Main. Далее, создаем пустой sln-файл, добавляем в него project.json файлы, как проекты. В каждый project.json следует прописать зависимости на проекты (раздел dependencies), пробуем скомпилировать. Если ошибок компиляции нет — поздравляю. Единственная проблема, что старый солюшен с csproj-проектами перестанет работать, чтобы оба проекта работали side by side есть решение. Выглядит довольно странно, но работает.

Что не будет работать


В нашем приложении столкнулись со следующими проблемами:
  • app.config — Разработчики corefx отказались от устаревшего API работы с конфигурационными файлами. Теперь конфигурации рекомендуется хранить в json файле.
  • PerformanceCounter — Windows специфика, для использования не на Windows платформе следует искать какую-то альтернативу.
  • DataSet, DataTable — считается устаревшими API.
  • LCID у CultureInfo — у культуры теперь нет свойства LCID, CultureInfo теперь можно создать только по имени.
  • Свойство Assembly у экземпляра Type  — чтобы получить описание сборки у типа необходимо использовать метод-расширение GetTypeInfo (). Ломает совместимость с текущим кодом, особенно в ресурсных файлах.
  • MachineKey — Windows специфика, нет возможности получить уникальный идентификатор текущей машины.
  • Thread.SetData, Thread.GetData — добавят во второй версии стандарта.

Это все, что касается API стандартной библиотеки. Очевидно, следует перерабатывать код использующий нативные вызовы (в нашем случае код проверки прав доступа и работа с дескрипторами безопасности). Файлы с таким legacy-кодом исключали из компиляции (раздел exclude в project.json) или отключали директивой условной компиляции (NETCOREAPP1_0).

SOAP


В текущей реализации .NET Core нет способа из коробки создать Web-сервис работающий по SOAP. Есть пример с MSDN, где показывают как можно при особом желании поддержать SOAP протокол. Мы для себя решили отказаться от SOAP и перевести веб-сервис на REST. Никаких проблем нет, ASP.NET Core не отличается от ASP.NET Web API. Есть DI с которым можно жить. Контроллеры, роуты, даже swagger работает — все на месте.

Остались еще большие проблемы: аутентификация пользователей (раньше это делал IIS) и какую библиотеку использовать для управления правами доступа, интеграции с LDAP.

Первую проблему можно решить поставив перед нашим приложением Apache с необходимым расширением и включив reverse proxy. Библиотеку для управления ACL еще не нашли.

Выводы


Visual Studio 2015 Update 3 и Resharper на проектах .NET Core работают идеально, с отладкой и скоростью компиляции проблем нет. Наконец-то для доставки приложения можно использовать Docker. Unit-тесты работают.

До полной уверенности нужно проводить нагрузочные тесты. Но в целом технология имеет право на жизнь, хоть и есть проблемы с тулингом: например, не поддерживается msbuild. Рекомендую .NET разработчикам присмотреться и начать использовать .NET Core в своих проектах. Для нас пока опыт только положительный.

Комментарии (0)

© Habrahabr.ru