Осуществимость совместного использования кода между .NET и Silverlight?
-
19-09-2019 - |
Вопрос
Я только что провел небольшую экспериментальную сессию , чтобы попытаться увидеть, сколько работы потребуется , чтобы добиться наших результатов.Сетевую библиотеку классов или, по крайней мере, ее части, в Silverlight, чтобы мы могли повторно использовать бизнес-логику между двумя мирами, мне интересно, есть ли у других опыт работы с подобными вещами.
То, что я заметил краем глаза:
- Отсутствует множество атрибутов (например, для просмотра (false)).
- Множество интерфейсов отсутствуют или присутствуют, но пусты (ICloneable скрыт, ITypedList отсутствует)
- Различия в отражении (все доступное должно быть общедоступным)
- Некоторые различия в базовом классе (нет компонента?)
Поэтому мне интересно, действительно ли для меня возможно даже рассматривать это как возможность?
Я запустил начальный код, но мне пришлось просто закомментировать большую часть базовой функциональности, в основном связанной со списками обработки, поскольку они основаны на ITypedList и некоторых базовых классах.Очевидно, мне нужно перейти на ObservableCollection в Silverlight, поэтому для того, чтобы справиться с этим, необходимо изменить весь базовый код.
Фактический класс бизнес-тестирования, который я создал, на 99,5% идентичен тому, который я бы сделал для .NET, только некоторые незначительные изменения, которые можно было бы легко использовать и в .NET, просто не так, как я бы сделал это до просмотра Silverlight.Другими словами, кажется возможным совместно использовать бизнес-логику при условии, что я могу сделать базовые классы совместимыми.
Просто чтобы мне было понятно, о чем я говорю, это о том, что у меня было бы в основном два файла проекта, один для .NET и один для Silverlight, но фактический исходный код C # был бы одним и тем же, общим для них обоих.
Итак, есть ли у кого-нибудь какой-нибудь опыт в этом?Есть какие-нибудь советы или рекомендации?
Будет ли оно того стоить?Это, безусловно, требует более тщательного изучения.
Решение
Это, безусловно, осуществимо.
Это сделано в рамках здешнего проекта;проект Silverlight включает в себя программы на C #, и есть некоторые #IF
операторы, обрабатывающие некоторые вещи (например, объявления log4net), а в других случаях просто повторно реализуются.Но в целом, это огромная победа, и вы обязательно должны попытаться это сделать (и, конечно же, мы успешно сделали).
-- Редактировать:
Один момент, однако, заключается в том, что наш OR / M (LLBLGen) не имел встроенной поддержки "простых" объектов для отправки через Silverlight;но кто-то написал плагин, который справился с этим, и это помогло.Поэтому, возможно, стоит подумать, какой тип DAL вы используете и насколько хорошо он поддерживает Silverlight.
Другие советы
Что я сделал, чтобы облегчить это, так это:
- Частое использование частичных классов и #if !SILVERLIGHT для разделения кода на части, с которыми Silverlight может справиться.
- Используйте генерацию кода везде, где это возможно.Например, я экспериментировал с шаблонами T4, которые генерируют атрибуты, эквивалентные Silverlight (например, DisplayAttribute вместо DescriptionAttribute)
- Всякий раз, когда есть интерфейс / атрибут, который не реализован Silverlight (например, IDeserializationCallback, ICloneable, INotifyPropertyChanging) Я создам фиктивный интерфейс с тем же именем в приложении Silverlight до тех пор, пока я знаю, что тот факт, что реализация не будет использоваться, не является проблемой.
- Наконец, стоит отметить, что в Серебряный свет 4, формат сборки действительно допускает совместное использование двоичных файлов между Silverlight и .NET при условии, что нет зависимостей, которые Silverlight не поддерживает.
Еще одно замечание об отдельных базовых классах - возможно, стоит создать абстрактный класс, производный от ObservableCollection в Silverlight и BindingList (или что бы вы ни использовали в .NET), чтобы минимизировать влияние на ваши типизированные коллекции.
Обновить Сегодня я работал над портированием некоторого .СЕТЕВОГО кода на Silverlight, который интенсивно использовал систему.Диагностические API, такие как TraceSource, SourceSwitch и т.д., Не существуют в Silverlight.Я создал очень минимальные реализации этих функций в проекте Silverlight и поместил их в пространство имен Einstein.Diagnostics.При этом я решил, что мне нужно соглашение, позволяющее легко идентифицировать код, имитирующий .NET Framework по сравнению смой собственный код.Поэтому я переименовал файлы-заполнители, поставив перед ними знак @.Я также добавил префиксы к именам классов в этих файлах.Самое приятное в этом то, что знак @ фактически не изменяет имена их классов с точки зрения компилятора C #.Итак, @SourceSwitch по-прежнему компилируется как Einstein.Диагностика.SourceSwitch, но в коде я легко вижу, что что-то не так.Я также украсил эти классы атрибутом [SilverlightPlaceholder].
Я делаю это с помощью protobuf-net и использую несколько подходов:
- условные символы компиляции в файле проекта для запуска тонких ветвей кода (да, это не идеально, но это работает)
- повторное знакомство с некоторыми вещами;примером здесь могут быть атрибуты - твой код по-прежнему может использовать повторно введенные атрибуты, даже если код фреймворка этого не делает;в качестве более экстремального примера этого, для compact framework мне пришлось повторно ввести значительную часть
Expression
API, который был забавным - просто отбрось кое-какие вещи;-p
Однако если вы используете ITypedList
(о чем вы упомянули), я вижу, что весь этот подход разваливается довольно беспорядочно;компонентная модель и так достаточно сложна, без необходимости пробиваться через хаки.Это действительно зависит от того, как далеко вы продвинулись по этому пути.Может быть, 4,0 / dynamic
откроются ли некоторые из этих опций снова?
Одно из возможных решений вашей проблемы - скопировать недостающий код из проекта Mono.Когда-то я делал небольшой проект с Compact Framework, и в нем отсутствовала вся система.Пространство имен XLM.Я просто скопировал все это из Mono в свой проект, скомпилировал его, и он отлично работал с минимальными изменениями, iirc.