Главная страница   /   11.1. Ограничения в коде (Метапрограммирование в .NET

Метапрограммирование в .NET

Метапрограммирование в .NET

Кевин Хазард

11.1. Ограничения в коде

Полностью новый API, который называется Windows Runtime, является фундаментом, на котором строятся приложения Windows 8, и вы обязательно столкнетесь с изменениями, когда начнете работать над приложениями для Windows 8. Если вы используете C#, или JavaScript, или C++ - это не имеет значения в Windows 8: каждый язык связывается с этими функции в той или иной форме. Основное различие в Windows 8 заключается в том, как рантайм API проецируется с языком. Простой пример можно увидеть с именами функций. В JavaScript имена функций, как правило, пишутся в CamelCase, а в .NET, Pascal написание является соглашением. Эти соглашения будут соблюдаться в проекциях языков, поэтому API кажется естественным для разработчиков.

Есть также ограничения в плане того, что можно и чего нельзя делать в приложении Windows 8. Кто-то работает с изолированным хранилищем. Вы не можете просто открыть файл с диска C, как в обычном .NET приложении. Вы должны использовать пространство имен Windows.Storage, которое ограничивает использование файлов в изолированной зоне вашего приложения. Для любителя метапрограммирования есть еще одно ограничение, и оно связано с Reflection.Emit.

Как вы видели в главе 5, для создания динамических типов во время выполнения вы должны использовать типы внутри пространства имен System.Reflection.Emit. В приложениях Windows 8 эти типы не проецируются к вам. Если вы наберете System.Reflection.Emit в Visual Studio 2012, вы увидите, что доступна лишь небольшая горстка перечислений; у вас нет доступа к AssemblyBuilder, TypeBuilder и так далее. Прокси библиотеки, mock фреймворки, генераторы динамической сериализации ... в Windows 8 нет способа создания динамических типов. Этот API не доступен по целому ряду причин.

Ну, это не совсем так. Вы не можете загрузить код, генерируемый во время выполнения, но вы можете загрузить код, сгенерированный со всем кодом, который вы упаковываете и отправляете в Windows Store. Поэтому вполне возможно, что вы сгенерируете все типы, которые вам нужны, в приложении, а затем загрузите их по мере необходимости, когда ваше приложение Windows 8 будет запущено. Тем не менее, это, кажется, несоответствием цели "динамического кода, генерируемого во время выполнения". Возможно, когда ваш код запущен, вам не нужно генерировать типы в зависимости от действий пользователя. Возможно, вам нужно только сгенерировать пару типов. Но с архитектурой Windows 8, у вас нет выбора. Если вашему приложению необходимо 145 динамических типов, вы должны создать все 145 через некоторого рода предварительную или посткомпиляционную процедуру, и включить эти типы и сборку, которая их содержит, в свой пакет. Это верно только для приложений Windows 8.

Совет

Есть несколько попыток преодолеть отсутствие Reflection.Emit в Windows 8. Одной из них является MoqRT (https://github.com/mbrit/moqrt#readme), который анализирует ваш код, чтобы выяснить, какие mock будут нужны в ваших тестах, и создает эти mock-объекты в статической сборке, на которую ссылается код. Далее существует прекомпилятор для сериализации, который называется protobuf (http://mng.bz/eD7u); он создает сборку, которую можно использовать в приложениях Windows 8. Также можно использовать Roslyn API для генерации кода на основе анализа исходного кода из приложений Windows 8, а также для автоматического добавления ссылок на эти автоматически сгенерированные сборки.

Если вы хотите создать приложение .NET 4.5, которое будет запускаться в Windows 8 через Windows 7 Desktop, вы можете это сделать. В этом случае все преимущества System.Reflection.Emit доступны для вас.