Net native framework что это
Подводя итоги
Конечно, в самой идее предлагать специализированный набор возможностей, удовлетворяющих определенными потребностям, нет ничего плохого. Это становится проблемой, когда отсутствует системный подход и специализация происходит на каждом слое без учета того, что происходит в соответствующих слоях других вертикалей. Последствием таких решения является набор платформ, которые имеют ряд общих API только потому, что они когда-то начинались из единой базы кода. Со временем, это приводит к росту различий, если только не проводить явные (и дорогие) упражнения для достижения единообразия API.
В какой момент возникает проблема с фрагментацией? Если вы нацелены только на одну вертикаль, то в реальности никакой проблемы нет. Вам предоставлен набор API, оптимизированный именно для вашей вертикали. Проблема проявляет себя, как только вы хотите делать что-то горизонтальное, ориентированное на множество вертикалей. Вот теперь вы задаетесь вопросом о доступности различных API и думаете, как производить блоки кода, которые работали бы на разных целевых вертикалях.
Известные проблемы и способы решения
Рождение переносимых библиотек классов (Portable Class Library, PCL)
К моменту выхода Windows 8 мы пришли к плану, как бороться с этой проблемой. Когда мы проектировали профиль Windows Store, мы ввели новую концепцию для лучшего моделирования подмножества: контракты.
Идея контрактов заключается в том, чтобы предоставить продуманный набор API, подходящих для задач декомпозиции кода. Контракты – это просто сборки, под которые вы можете компилировать свой код. В отличие от обычных сборок, сборки контрактов спроектированы именно под задачи декомпозиции. Мы четко прослеживаем зависимости между контрактами и пишем их так, чтобы они отвечали за что-то одно, а не были свалкой API. Контракты имеют независимую версионность и следуют соответствующим правилам, например, если добавляется новый API, то он будет доступен в сборке с новой версией.
Сегодня мы используем контракты для моделирования API во всех вертикалях. Вертикаль может просто взять и выбрать, какие контракты она будет поддерживать. Важным моментом является то, что вертикаль обязана поддерживать контракт целиком или не поддерживать вовсе. Другими словами, она не может включить в себя подмножество контракта.
Это позволяет говорить о различиях в API между вертикалями уже на уровне сборок в отличие от индивидуальных различиях в API, как это было раньше. Это позволяет нам реализовать механизм библиотек кода, которые нацелены на множество вертикалей. Такие библиотеки сегодня известны как переносимые библиотеки классов (portable class libraries).
Итоги
На нас лежит ответственность за продолжение выпуска критичных обновлений безопасности, не требующих работы со стороны разработчиков приложений, даже если затрагиваемые компоненты распространятся эксклюзивно как NuGet-пакеты.
А вот и другие наши статьи по схожей тематике:
Что нового приносит UWP?
Различия настроек компиляции в отладке и релизе
Локальная нативная компиляция с релизной конфигурацией позволяет вам протестировать приложение в окружении, близком к тому, что будет у конечного пользователя. Важно регулярно тестировать в таком режиме по мере разработке.
Все три архитектуры выбраны по умолчанию
Важно отметить, что вы по-прежнему можете собирать AnyCPU-библиотеки и использовать соответствующие DLL в вашем UWP-приложении. Эти компоненты будут скомпилированы в бинарные библиотеки под соответствующие архитектуры, указанные в настройках проекта.
Пакет .appxupload отправляется в магазин; папка Test содержит пакет appx для локальной устровки
Два следствия из этого: первое, вы как разработчик более не имеете доступа к номеру ревизии вашего приложения (четвертое число). Магазин резервирует это число как способ версионирования пакета приложения, если по какой-либо причине потребуется перекомпиляция в облаке. Не беспокойтесь, вы по-прежнему можете управлять тремя другими числами.
Выберите “Yes” для загрузки в магазин
Когда вы используете помощника для создания пакетов приложения, вам нужно выбрать “Yes” в ответ на вопрос Visual Studio, хотите ли вы создать пакет для загрузки в магазин. Я также рекомендую выбрать “Always” для опции “Generate app bundle”, что приведет к созданию единого файла .appxupload, готового для загрузки. Полная инструкция по созданию пакетов для магазина доступна в статье «Пакетирование универсальных приложений Windows для Windows 10».
- Регулярно тестируйте ваше приложение в режиме релиза
- Убедитесь, что вы оставляете номер ревизии пакета как 0. Visual Studio не даст вам его изменить, но также не стоит это делать в других редакторах.
- Загружайте в магазин только .appxupload, собранные в процессе создания пакета для магазина, если вы загрузите .appx для UWP-приложения, вы получите ошибку в магазине.
Готов для корпоративного использования
Заключение
Выражаю благодарность за рецензирование статьи экспертам Кино Агилере (Kino Aguilar), Адаму Деннингу (Adam Denning), Ишаю Галатцеру (Yishai Galatzer), Дженни Хейз (Jenny Hayes), Джереми Менгу (Jeremy Meng), Харикришне Менону (Harikrishna Menon), Джессике Принс (Jessica Prince), Унни Равиндранатану (Unni Ravindranathan), Навиту Саксене (Navit Saxena), Майклу Стреховски (Michael Strehovsky), Дебби Торн (Debbie Thorn), Мэтью Уалду (Matthew Whilde), Лусиану Вишику (Lucian Wischik).
Различия настроек компиляции в отладке и релизе
Локальная нативная компиляция с релизной конфигурацией позволяет вам протестировать приложение в окружении, близком к тому, что будет у конечного пользователя. Важно регулярно тестировать в таком режиме по мере разработке.
Все три архитектуры выбраны по умолчанию
Важно отметить, что вы по-прежнему можете собирать AnyCPU-библиотеки и использовать соответствующие DLL в вашем UWP-приложении. Эти компоненты будут скомпилированы в бинарные библиотеки под соответствующие архитектуры, указанные в настройках проекта.
Пакет .appxupload отправляется в магазин; папка Test содержит пакет appx для локальной устровки
Два следствия из этого: первое, вы как разработчик более не имеете доступа к номеру ревизии вашего приложения (четвертое число). Магазин резервирует это число как способ версионирования пакета приложения, если по какой-либо причине потребуется перекомпиляция в облаке. Не беспокойтесь, вы по-прежнему можете управлять тремя другими числами.
Выберите “Yes” для загрузки в магазин
Когда вы используете помощника для создания пакетов приложения, вам нужно выбрать “Yes” в ответ на вопрос Visual Studio, хотите ли вы создать пакет для загрузки в магазин. Я также рекомендую выбрать “Always” для опции “Generate app bundle”, что приведет к созданию единого файла .appxupload, готового для загрузки. Полная инструкция по созданию пакетов для магазина доступна в статье «Пакетирование универсальных приложений Windows для Windows 10».
- Регулярно тестируйте ваше приложение в режиме релиза
- Убедитесь, что вы оставляете номер ревизии пакета как 0. Visual Studio не даст вам его изменить, но также не стоит это делать в других редакторах.
- Загружайте в магазин только .appxupload, собранные в процессе создания пакета для магазина, если вы загрузите .appx для UWP-приложения, вы получите ошибку в магазине.
JIT-компиляция
Так как входные данные .NET Native — промежуточный язык (IL) и метаданные, записанные в сборки управляемого кода, то вы по-прежнему можете выполнять создание собственного кода или другие пользовательские операции посредством событий "перед сборкой" и "после сборки" или путем изменения файла проекта MSBuild.
Везде, где возможно, делается попытка исключить все метаданные.
.exe — исполняемый файл-заглушка, который просто передает управление Специальному Main экспорту в .dll.
mrt100_app.dll — оптимизированная среда выполнения, которая предоставляет сервисы реального времени, такие как сборка мусора.
APPX-манифестом приложения регистрируются все зависимости. Помимо EXE-файла приложения, библиотеки DLL и среды выполнения mrt100_app.dll, которые входят непосредственно в APPX-пакет, пакет включает два дополнительных файла:
msvcr140_app.dll — библиотека языка C времени выполнения (CRT), используемая mrt100_app.dll. Она включается по ссылке платформы в пакете.
mrt100.dll. Эта библиотека содержит функции, которые могут повысить производительность библиотеки mrt100_app.dll, хотя ее отсутствие не препятствует функционированию mrt100_app.dll. Она загружается из папки system32 на локальном компьютере, если там она имеется.
динамический вызов или вызов посредством позднего связывания;
сериализация и десериализация;
NuGet как первоклассный механизм доставки
Для слоя BCL у нас будет прямое соответствие между сборками и пакетами NuGet.
В дальнейшем NuGet-пакеты будут иметь те же имена, что и сборки. К примеру, неизменяемые коллекции перестанут распространяться под именем Microsoft.Bcl.Immutable и вместо этого будут в пакет, называющемся System.Collections.Immutable.
В дополнение, мы решили использовать семантический подход для версионности сборок. Номер версии NuGet-пакета будет согласован с версией сборки.
Согласованность именования и версионности между сборками и пакетами сильно облегчит их поиск. У вас не должно возникнуть вопроса, в каком пакете содержится System.Foo, Version=1.2.3.0 – он находится в пакете System.Foo с версией 1.2.3.
Основа для открытого кода и кросс-платформенности
Из прошлого опыта мы знаем, что успех открытого кода зависит от сообщества вокруг него. Ключевой аспект этого – это открытый и прозрачный процесс разработки, который позволит сообществу участвовать в ревью кода, знакомиться с документам по проектированию и вносить свои изменения в продукт.
Конечно, отдельные компоненты, например, файловая система, требуют отдельной реализации. Модель доставки через NuGet позволяет нам абстрагироваться от этих различий. Мы можем иметь единый NuGet-пакет, предоставляющий различные реализации для каждого из окружений. Однако важный момент тут как раз в том, что это внутренняя кухня реализации компонента. С точки зрения разработчика это единый API, который работает на разных платформах.
Наличие всех трех элементов позволяет нам добиться широкого спектра гибкости и зрелости решений:
Нам кажется, что мы нашли хороший баланс между тем, чтобы заложить основу для будущего, сохраняя при этом хорошую совместимость с существующими стеками. Давайте посмотрим детальнее на часть из этих платформ.
Объединение формы API против объединения реализаций
Намного лучше унифицировать реализации: вместо того, чтобы только предоставлять хорошо декомпозированное описание, мы должные подготовить декомпозированную реализацию. Это позволит вертикалям просто использовать одну и ту же реализацию. Сближение вертикалей больше не будет требовать дополнительных действий; оно достигается просто за счет правильного конструирования решения. Конечно все равно будут случаи, в которых необходимы различные реализации. Хороший пример этого – это файловые операции, требующие использования разных технологий в зависимости от окружения. Однако, даже в этом случае намного проще попросить каждую команду, отвечающую за конкретные компонент, подумать, как из API будут работать в разных вертикалях, чем постфактум пытаться предоставить единый набор API поверх. Переносимость – это не есть что-то, что вы можете добавить после. К примеру, наш File API включает поддержку Windows Access Control Lists (ACL), которые не поддерживаются всем окружениями. При дизайне API нужно учитывать такие моменты и, в частности, предоставлять подобную функциональность в отдельных сборках, которые могут отсутствовать на платформах, не поддерживающих ACL.
Что нового в NuGet?
В UWP встроена поддержка NuGet 3.1. В эту версию включены средства, которые улучшают управление зависимостями пакетов и локальное кеширование ваших пакетов для повторного использования в нескольких проектах.
Смена packages.config на project.json позволяет «перезагружать» ссылки в проектах, и теперь есть новая транзитивная зависимость, поддерживаемая NuGet. Раньше, когда вы ссылались на пакет, который ссылался на другой NuGet-пакет, управлять версиями пакета было весьма затруднительно. Например, NHibernate — это пакет, зависимый от lesi.collections. В packages.config было бы две ссылки — по одной на каждый пакет. Когда вы хотите обновить NHibernate, обновляете ли вы и lesi.collections? Или, если появится обновление для lesi.collections, должны ли вы обновить и NHibernate для поддержки новых средств? Все это запросто превращается в запутанный цикл, из-за которого сложно управлять версиями пакетов. Функциональность транзитивных зависимостей (transitive dependencies feature) NuGet абстрагирует это решение для обновления ссылок пакета с использованием улучшенной семантики контроля версий в файлах определения пакетов (nuspecs).
Кроме того, NuGet теперь скачивает и сохраняет копии используемых вами пакетов в папке глобальных пакетов — %userprofile%\.nuget\packages. Это не только повышает эффективность вашего труда, потому что от вас требуется лишь раз скачать каждый пакет, но и уменьшает дисковое пространство, занимаемое пакетами на вашей рабочей станции, поскольку от проекта к проекту используются одни и те же двоичные файлы пакетов.
Подводя итоги
Создание собственных двоичных файлов
Метаданные, описывающие сборку, ее зависимости, типы, которые она содержит, и их члены. Метаданные используется для отражения и доступа через позднее связывание, а также в некоторых случаях для средств компиляции и построения.
Код реализации. Он состоит из кодов операций промежуточного языка (IL). Во время выполнения JIT-компилятор преобразует его в машинный код для целевой платформы.
В дополнение к основной сборке приложения для приложения требуется следующее:
Все дополнительные библиотеки классов и сборки сторонних производителей, необходимые приложению. Эти сборки точно так же включают метаданные, описывающие сборку, ее типы и члены, а также IL-код, который реализует все члены типов.
Обратите внимание, для успешного выполнения приложения должны присутствовать: вся среда CLR, метаданные, IL-код для всех типов в сборках, специфичных для приложения, сторонние сборки и системные сборки.
Фреймворки для всей машины против локальных фреймворков для приложения
- Централизованное обслуживание
- Уменьшает размер требуемого места на диске
- Позволяет разделять нативный код между приложениям
- Добавление интерфейса к существующему типу может нарушить работу приложений, так как это может повлиять на то, как тип сериализуется.
- Добавление перегрузки к методу, который раньше не имел любых перегрузок может нарушить работу с рефлексиями в тех случаях, когда в коде не обрабатывается вероятность найти более, чем один метод.
- Переименование внутреннего типа может нарушить приложения, если имя типа определялось через метод ToString().
Это все очень редкие случаи, но, когда у вас пользовательская база в 1.8 миллиарда машин, быть совместимым с 99.9% по-прежнему означает, что 1.8 миллиона машин затронуто.
Такой подход в общем-то почти полностью снимает все проблемы, мешающие вам обновиться до свежей версии. Ваши возможности перейти на новую версию ограничены только вашей возможностью выпустить новую версию вашего приложения. Это также означает, что вы контролируете, какая версия библиотеки используется конкретным приложением. Обновления производятся в контексте одного приложения, никак не затрагивая другие приложения на той же машине.
Это позволяет выпускать обновления в гораздо более гибкой манере. NuGet также предлагает возможность попробовать предварительные версии, что позволяет нам выпускать сборки без строгих обещаний относительно работы конктретных API. Такой подход позволяет нам поддерживать процесс, в котором мы предлагаем вам наш свежий взгляд на дизайн сборки – и, если вам не нравится, просто его изменить. Хороший пример это – это неизменяемые коллекции (immutable collections). Бета-период длился порядка 9 месяцев. Мы потратили много времени, пытаясь добиться правильного дизайна прежде, чем выпустить первую версию. Нет необходимости говорить, что финальная версия дизайна библиотеки, — благодаря вашим многочисленным отзывам, — намного лучше, чем начальная.
Windows Store и Windows Phone
Более детально выбор между двумя подходами описан в статье «Sharing code across platforms».
Известные проблемы и способы решения
Конфигурация компиляции Debug и Release
Локальная компиляция в «родной» (неуправляемый) код через конфигурацию Release позволит протестировать ваше приложение в среде, похожей на ту, с которой имеют дело потребители. Важно тестировать это на регулярной основе по мере продвижения в разработке! Тестируя приложение с применением генерации кода и исполняющей среды, вы будете уверены в том, что отловили все возможные ошибки (например, условия потенциальных гонок).
Учитывая сказанное, вы можете по-прежнему компилировать библиотеки и DLL в конфигурации AnyCPU, чтобы ссылаться на них в своем UWP-приложении. Эти компоненты будут компилироваться в специфичные для архитектуры процессора двоичные файлы на основе конфигурации проекта (.appx), использующего их.
Рис. 2. Открытие Configuration Manager
В раскрывающемся списке Active solution configuration выберите , чтобы создать новую конфигурацию, как показано на рис. 3.
Рис. 3. Создание новой конфигурации
Читайте также: