Преобразование сборок .NET в сборки Silverlight

ОГЛАВЛЕНИЕ

Демонстрация преобразования сборок .NET в сборки Silverlight

Введение

Данная статья решает проблему, представленную Дэвидом Бетзом в своей статье Повторное использование сборок .NET в Silverlight, путем создания простого консольного приложения, запускаемого в послесборочных командах.

Краткая информация

Теперь, когда вышла вторая версия Silverlight, используемая растущим числом разработчиков, на основе каркаса разрабатываются более продвинутые приложения.

Одной из эффективных особенностей Silverlight является возможность его соединения с сервисами WCF(основы связи Windows). Так как большинство разработчиков решает реализовать контрактные классы в открытой сборке, на которую затем ссылаются конструктор сервиса и клиент, проблема возникает при попытке сослаться на эту открытую сборку через приложение Silverlight.

Не будем разбирать подробно, почему Visual Studio не дает добавлять не? Silverlight сборки в проект Silverlight, так как это детально представлено в статье Дэвида Бетза. Но вкратце, сборки, используемые Silverlight (System.dll, mscorlib.dll etc.), не являются точно такими же, как и основные сборки .NET, хотя многие функции есть и в тех, и в других. Сборки Silverlight являются сокращенной версией полных сборок .NET, но  и те, и другие почти одинаковы по предоставляемым функциям.
По сути, если изменить открытую сборку так, чтобы она ссылалась на Silverlight-версию этих сборок без изменения кода, то можно повторно использовать открытую сборку в приложении Silverlight.

Сборки MSIL

Когда вы пишете код на любом языке .NET (C#, VB.NET), компилятор компилирует код в то, что называется MSIL, или промежуточный язык Microsoft. Затем этот код собирается в сборку .NET, загружаемую и динамически компилируемую во время выполнения. Так как ссылки сборки проверяются лишь во время выполнения, можно безопасно менять ссылки спорных сборок на правильные сборки Silverlight в коде IL, и когда сборка загружается посредством Silverlight, правильные сборки уже будут находиться в памяти, и динамичный компилятор скомпилирует код в зависимости от них.

Цель

После того как сборка собрана, надо снова разобрать ее в MSIL, внести несколько изменений в ссылки (возможно, удалить некоторые атрибуты, не поддерживаемые Silverlight-версией ссылок), и вновь собрать код в новую сборку, которую способен использовать Silverlight.

Замечание: вновь созданная сборка может использоваться лишь из проекта Silverlight, но все сигнатуры типов будут тождественны исходной сборке, поэтому можно будет делиться контрактами WCF между обоими.

Создание приложения

Включенный код – простое консольное приложение, написанное на C#. Его сопровождает XML файл, содержащий все настройки, необходимые ему для запуска.

Приложению надо знать следующую информацию:
1.    Расположение ассемблера и дизассемблера MSIL (ilasm.exe и ildasm.exe).
2.    Список сборок, меняющихся между их реализацией Silverlight и их аналоги .NET.
3.    Список любых неподдерживаемых атрибутов, расположенных в исходных сборках .NET, и тех, которые не существуют в Silverlight и должны быть удалены из кода IL.

Файл XML выглядит так:

<?xml version="1.0" encoding="utf-8" ?>
<SLAsm.Settings xmlns="urn:Silverlight-Assmblies/SLAsmSettings.xsd"
    ILAssembler="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ilasm.exe"
    ILDisassembler="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\ildasm.exe">
     <ExternAssembly Name="System" Version="2.0.5.0"
         PublicKeyToken="7C EC 85 D7 BE A7 79 8E" />
     <ExternAssembly Name="mscorlib" Version="2.0.5.0"
         PublicKeyToken="7C EC 85 D7 BE A7 79 8E" />
     <ExternAssembly Name="System.Core" Version="2.0.5.0"
         PublicKeyToken="7C EC 85 D7 BE A7 79 8E" />
     <ExternAssembly Name="System.Net" Version="2.0.5.0"
         PublicKeyToken="7C EC 85 D7 BE A7 79 8E" />
     <ExternAssembly Name="System.Runtime.Serialization"
         Version="2.0.5.0" PublicKeyToken="7C EC 85 D7 BE A7 79 8E" />
     <ExternAssembly Name="System.Windows"
         Version="2.0.5.0" PublicKeyToken="7C EC 85 D7 BE A7 79 8E" />
     <ExternAssembly Name="System.Json"
         Version="2.0.5.0" PublicKeyToken="31 BF 38 56 AD 36 4E 35" />
     <ExternAssembly Name="System.ServiceModel"
         Version="2.0.5.0" PublicKeyToken="31 BF 38 56 AD 36 4E 35" >
          <UnsupportedAttribute>
            System.ServiceModel.FaultContractAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.DeliveryRequirementsAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.CallbackBehaviorAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.MessageHeaderAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.MessageHeaderArrayAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.MessagePropertyAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.OperationBehaviorAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.ServiceBehaviorAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.XmlSerializerFormatAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.PeerHopCountAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.TransactionFlowAttribute
          </UnsupportedAttribute>
          <UnsupportedAttribute>
            System.ServiceModel.Activation.AspNetCompatibilityRequirementsAttribute
          </UnsupportedAttribute>
     </ExternAssembly>
</SLAsm.Settings>

Не забудьте задать правильные пути в файлах ILAsm.exe и ILdasm.exe

Файл был предварительно заполнен всеми ссылками на сборки Silverlight, и список неподдерживаемых атрибутов был добавлен в сборку System.ServiceModel.

Замечание: это не полный список неподдерживаемых атрибутов, лишь те, с которыми мы столкнулись. Добавляйте любые атрибуты, не работающие с Silverlight. (Приложение Silverlight генерирует TypeLoadException при попытке загрузить сборку.)