Как сделать версию Silverlight существующего кода C #, который опирается на пространство имен System.Drawing - PullRequest
5 голосов
/ 09 декабря 2010

У нас в значительной степени есть код C # 2.0, который сильно зависит от пространства имен System.Drawing.Также есть некоторые зависимости WinGDI (через взаимодействие).

Как бы вы порекомендовали решить проблему создания функционально эквивалентной версии кода Silverlight?Мы хотим максимально использовать код, потому что хотим продолжить разработку обеих версий кода.

Может быть, есть какие-то статьи / книги, которые вы могли бы порекомендовать?невизуальная составляющая.Не приложение.Сторонних зависимостей нет.

Ответы [ 6 ]

4 голосов
/ 10 декабря 2010

У меня большой опыт создания версий программного обеспечения wpf / silverlight, которые создавались с использованием winforms.Это печально, но в вашем случае, когда вы используете много взаимодействия и System.Drawing, это практически невозможно сделать.

Конечно, вы всегда можете попытаться (и на самом деле всегда должны) отделить свою бизнес-логику от интерфейса, но в такой ситуации (я надеюсь, что я ошибаюсь!) Ваш интерфейс должен быть полностью переработаниз-за различий в архитектуре winforms и wpf / silverlight.

По моему опыту, эта проблема решена следующим образом: все старые компоненты winforms остались прежними, но все новые функции были созданы с использованием wpf с помощьювнедрение элементов управления wpf в приложение winforms.

Да, иногда это странно, но это действительно более продуктивно, чем просто тратить весь свой старый код и тратить огромное количество времени и денег на новый, что делает то же самое.

3 голосов
/ 14 декабря 2010

Если нет графического интерфейса, и вы все еще используете много System.Drawing Я думаю, что этот компонент связан с манипулированием изображениями в памяти.

Если это так, из-за очень высокой стоимостипортирование всего кода, если это вообще возможно, вы можете изменить свою архитектуру.

У вас есть старый код на стороне сервера, где вы можете свободно использовать эти API, и предоставить необходимую функциональность вашему Silverlight.приложение через какой-то веб-сервис.Если компонент не имеет графического интерфейса, это должно быть очень выполнимо.

Редактировать: Добавление предложений о том, как это может быть уместно для разработчиков

Возможно, это все еще может работать - если вашРазработчик планирует развернуть этот элемент управления Silverlight на веб-странице, тогда он, вероятно, имеет веб-сервер, на котором он может разместить ваш компонент для доступа к коду Silverlight.

Если разработчик планирует развернуть ваш код Silverlight вВ режиме без браузера вы можете создать версию, в которую будет встроен старый компонент (например, в виде COM-объекта).

Дополнительной альтернативой вышеперечисленному будет размещение этого компонента на сервере самостоятельно.или в каком-либо общедоступном облаке, например Windows Azure.

2 голосов
/ 10 декабря 2010

В зависимости от того, как ваша существующая кодовая база спроектирована, это может быть невозможно, но вы можете загрузить элементы управления Forms внутри WPF, см. этот пример . Если ваш унаследованный код упакован в элементы управления, вы можете получить много повторного использования кода. Надеюсь, это поможет.

2 голосов
/ 09 декабря 2010

Это будет почти невозможно, так как WPF и Silverlight в корне отличаются от старых версий. Если вы действительно хотите иметь возможность разрабатывать настольные и веб-приложения одновременно, вам, вероятно, будет лучше использовать WPF и Silverlight.

Единственная проблема, это повторное использование кода, все еще сложно, потому что Silverlight не имеет всех функций, которые имеет WPF. Кроме того, модель доступа к данным в Silverlight полностью асинхронна.

Лучше всего создать приложение в Silverlight и затем портировать это приложение в WPF.

Вероятно, не тот ответ, который вы искали.

1 голос
/ 16 ноября 2011

Прежде всего, вы должны принять, что некоторые функции оригинального кода не перейдут в версию Silverlight . Взаимодействие, чтение и запись файлов - такие вещи либо запрещены по соображениям безопасности, либо просто не поддерживаются.

Второе, что нужно иметь в виду, это то, что ваш код будет загрязнен условной компиляцией (если вы захотите продолжить поддерживать сборку версии .NET из той же базы кода).

И третье - вам придется написать новый код (вместо удаленного кода). Например, вам может потребоваться создать новые методы, которые принимают WriteableBitmap вместо методов, которые принимают System.Drawing.Bitmap, чтобы предоставить пользователям версии Silverlight аналогичный набор функций.

Хорошо, давайте посмотрим, что вам может понадобиться для создания Silverlight-версии библиотеки .NET.

  1. Создание нового проекта для версии Silverlight
  2. Добавить все существующие файлы кода в этот проект как ссылки .
  3. Попробуйте построить проект. Скорее всего, сборка не удастся со многими предупреждениями и сообщениями об ошибках. Очевидно, что цель состоит в том, чтобы исправить их все.

Вот несколько советов о том, что можно сделать для исправления распространенных ошибок сборки.

  1. Удалите все ненужные директивы using namespace-name. Исключите неподдерживаемые пространства имен с помощью условной компиляции, например:
#if !SILVERLIGHT
    using System.Drawing;
#endif
  1. Если вы используете перечисления, отсутствующие в Silverlight (например, System.Drawing.Imaging.ImageFormat), то введите эквивалентные настраиваемые перечисления (например, MyImageFormat) и измените внутренний код, чтобы использовать только настраиваемые перечисления. При необходимости добавьте перегруженные методы, которые используют настраиваемые перечисления (или эквивалентные перечисления Silverlight) в общедоступный интерфейс.

  2. Аналогично для структур (например, System.Drawing.PointF) или измените код, чтобы использовать более простые типы (например, два float с вместо PointF структуры)

  3. Исключить открытый и закрытый код, который использует неподдерживаемые структуры с условной компиляцией. Попробуйте переписать внутренний код, чтобы он использовал только языковые конструкции, поддерживаемые в .NET и Silverlight.

  4. Создайте класс-оболочку для доступа к встроенным ресурсам в версии Silverlight, поскольку не будет готовых оболочек, которые предоставят вам byte[] или string для двоичных и текстовых ресурсов.

  5. Создать свойство как это

    public static Encoding DefaultEncoding
    {
        get
        {
    #if SILVERLIGHT
            return Encoding.UTF8;
    #else
            return Encoding.Default;
    #endif
        }
    }

И используйте это свойство вместо Encoding.Default в вашем коде.

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

Если вы используете nunit для модульного тестирования вашей версии .NET, то вы можете взглянуть на nunit-silverlight (проверьте эту страницу тоже) для тестирования версии Silverlight. Однако есть некоторые оговорки.

  1. TestCaseSource атрибут не поддерживается nunit-silverlight.
  2. Чтение локальных файлов не поддерживается.

Если вам нужно читать или записывать локальные файлы в своих тестах, то вы должны использовать Silverlight 4 для своего тестового приложения. Это невозможно сделать в Silverlight 3. Вам также следует настроить тестовое приложение как приложение Out-of-Browser и предоставить ему повышенные права доверия (отметьте «требуют повышенного доверия» в настройках Out-of-Browser)

Вам понадобится оболочка (да, еще одна) для чтения и записи локальных файлов, потому что тесты Silverlight смогут использовать и генерировать только байтовые буферы и потоки.

Вот некоторые фрагменты кода, которые могут быть полезны для оболочки:

Получить путь к текущей папке:

Uri uri = new Uri(System.Windows.Application.Current.Host.Source, relativeFileName);
var currentPath = uri.OriginalString;

Обратите внимание, что вам нужно удалить file:// с начала currentPath

Чтение локальных файлов (через COM Automation)

private static byte[] readBinaryFile(string fileName)
{
    const int adTypeBinary = 1;

    using (dynamic adoCom = System.Runtime.InteropServices.Automation.AutomationFactory.CreateObject(@"ADODB.Stream"))
    {
        adoCom.Type = adTypeBinary;
        adoCom.Open();
        adoCom.LoadFromFile(fileName);

        return adoCom.Read();
    }
}

Запись локальных файлов (также через COM Automation)

private static void writeBinaryFile(string fileName, byte[] binaryArray)
{
    const int adTypeBinary = 1;
    const int adSaveCreateOverWrite = 2;
    using (dynamic adoCom = System.Runtime.InteropServices.Automation.AutomationFactory.CreateObject(@"ADODB.Stream"))
    {
        adoCom.Type = adTypeBinary;
        adoCom.Open();
        adoCom.Write(binaryArray);
        adoCom.SaveToFile(fileName, adSaveCreateOverWrite);
    }
}

Вы также можете проверить Silverlight COM Toolkit . Но я им не пользуюсь.

Удачи!

1 голос
/ 15 декабря 2010

Вот еще одна дикая идея.

Изолируйте все свои System.Drawing, PInvoke, GDI и т. Д. В отдельный компонент и оберните их как объект ActiveX.

Вставьте объект ActiveX на веб-страницу и заставьте приложение Silverlight каким-либо образом использовать его сервисы. Я полагаю, что для этого потребуется некоторая «прокладка» уровня веб-страницы (например, сценарий, который активирует объект ActiveX и предоставляет результаты приложению Silverlight через документ или что-то в этом роде)

Это просто первоначальная мысль, которая у меня была. Я думаю, это можно улучшить разными способами. Как вы думаете? :)

Редактировать: Если для вашего кода Silverlight приемлемо выполнение в режиме вне браузера, то Silverlight 4 поддерживает встраивание элемента управления ActiveX в приложение Silverlight. Это может сделать возможным обернуть всю вашу старую реализацию в некоторый ActiveX и использовать ее из Silverlight.

...