[Из песочницы] Портирование большого проекта на .NET Core
Задача: обеспечить работу системы на Linux без потери в производительности с минимальными телодвижениями.
Напрашиваются 3 варианта решения задачи:
- Использовать Mono
- Использовать .NET Core
- Переписать все на 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 в своих проектах. Для нас пока опыт только положительный.