Преобразование сборок .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 при попытке загрузить сборку.)