Как лучше всего скомпилировать Silverlight и WPF в одном проекте?

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

Конфигурация: Silverlight сгенерирует: Company.Controls.Silverlight.dll

Конфигурация: WPF сгенерирует: Company.Controls.Wpf.dll

Возможно ли, чтобы один и тот же источник в одном файле был разделен с помощью определений?

Кто-нибудь делал это раньше?

Редактировать: Я создал решение для каждого проекта, например MyCompany.Windows.Controls, которое затем содержит 2 проекта: MyCompany.Windows.Controls и MyCompany.Windows.Controls.Silverlight. Наряду с этими двумя папками у меня есть папка «Shared», которая содержит файлы, используемые обоими проектами. Пока работает хорошо :)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
4 191
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Обновление: показывает, что почти всегда есть более простой способ. :-)

Первый шаг - использовать условную компиляцию для разделения кода, специфичного для Silverlight. (Я предполагаю, что ваша цель "по умолчанию" - WPF.)

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

Взгляните на Калибурн проект с открытым исходным кодом. Он все это делает.

Вот пример из класса ExtensionMethods от Caliburn.

    public static T GetResource<T>(this FrameworkElement element, object key)
        {
            DependencyObject currentElement = element;

            while (currentElement != null)
            {
                var frameworkElement = currentElement as FrameworkElement;

                if (frameworkElement != null && frameworkElement.Resources.Contains(key))
                    return (T)frameworkElement.Resources[key];

#if !SILVERLIGHT
                currentElement = (LogicalTreeHelper.GetParent(currentElement) ??
                    VisualTreeHelper.GetParent(currentElement));
#else
                currentElement = VisualTreeHelper.GetParent(currentElement);
#endif
            }

            if (Application.Current.Resources.Contains(key))
                return (T)Application.Current.Resources[key];

            return default(T);
        }

Если вы откроете Caliburn в VS и скомпилируете его, он будет соответствовать стандартной структуре. Ссылки относятся к .NET 3.5 и WPF, а не к Silverlight. Вот почему директивы предварительной обработки - "! SILVERLIGHT".

В вашем сценарии сборки (Caliburn использует NAnt) у вас будет цель, которая устанавливает определения для каждой платформы, например, цель Silverlight Caliburn:

<target name = "config-platform-silverlight20">
    <property name = "nant.settings.currentframework" value = "silverlight-2.0"/>
    <property name = "build.platform" value = "silverlight-2.0"/>
    <property name = "build.defines" value = "${global.build.defines},SILVERLIGHT,SILVERLIGHT_20,NO_WEB,NO_REMOTING,NO_CONVERT,NO_PARTIAL_TRUST,NO_EXCEPTION_SERIALIZATION,NO_SKIP_VISIBILITY,NO_DEBUG_SYMBOLS"/>
    <property name = "current.path.bin" value = "${path.bin}/silverlight-2.0/${build.config}"/>
    <property name = "current.path.test" value = "${path.bin}/silverlight-2.0/tests" />
    <property name = "current.path.lib" value = "${path.lib}/Silverlight" />
</target>

Тогда вот цель, которая вызывает фактическую сборку Silverlight:

<target name = "platform-silverlight20" depends = "config">
    <if test = "${framework::exists('silverlight-2.0')}">
        <echo message = "Building Caliburn ${build.version} for Silverlight v2.0."/>
        <call target = "config-platform-silverlight20"/>
        <copy todir = "${current.path.bin}">
            <fileset basedir = "${current.path.lib}">
                <include name = "*.dll"/>
                <include name = "*.xml"/>
            </fileset>
        </copy>
        <call target = "core"/>
        <call target = "messaging"/>
        <call target = "actions"/>
        <call target = "commands"/>
        <call target = "package-platform"/>
    </if>
    <if test = "${not(framework::exists('silverlight-2.0'))}">
        <echo message = "Silverlight v2.0 is not available. Skipping platform."/>
    </if>
</target>

Наконец, вот пример «основной» цели, которая отвечает за создание Caliburn.Core.dll:

<target name = "core" depends = "config, ensure-platform-selected">
    <mkdir dir = "${current.path.bin}"/>
    <csc keyfile = "${path.src}/Caliburn.snk" noconfig = "true" warnaserror = "false" target = "library" debug = "${build.debug}" optimize = "${build.optimize}" define = "${build.defines}"
     output = "${current.path.bin}/Caliburn.Core.dll"
     doc = "${current.path.bin}/Caliburn.Core.xml">
        <sources basedir = "${path.src}">
            <include name = "${build.asminfo}"/>
            <include name = "Caliburn.Core/**/*.cs"/>
        </sources>
        <references basedir = "${current.path.bin}">
            <include name = "mscorlib.dll"/>
            <include name = "System.dll"/>
            <include name = "System.Core.dll"/>
            <!--WPF-->
            <include name = "PresentationCore.dll"/>
            <include name = "PresentationFramework.dll"/>
            <include name = "WindowsBase.dll"/>
            <!--Silverlight-->
            <include name = "System.Windows.dll" />
        </references>
        <nowarn>
            <warning number = "1584"/>
        </nowarn>
    </csc>
</target>

Обратите внимание на то, как он ссылается на необходимые сборки.

Возможно, вам потребуется отредактировать файл NAnt.exe.config (если вы используете NAnt), чтобы он соответствовал правильной версии платформы Silverlight. Для Silverlight RTW версия фреймворка будет 2.0.31005.0.

Я думаю, что сейчас правильная ссылка для проекта Caliburn: codeplex.com/caliburn

bperreault 10.09.2009 21:37
Ответ принят как подходящий

Я сам не пробовал (все еще пытаюсь найти время поиграть с Silverlight), но не могли бы вы иметь одно решение с двумя проектами, один нацелен на Silverlight, а другой на .NET 3.5, и добавить общие файлы классов в каждый проект как ссылки (щелкните проект правой кнопкой мыши, «Добавить существующий элемент ...», «Добавить как ссылку»)?

** Обновление: см. Ответ Марка ниже относительно Project Linker. Я использовал это в своем многоцелевом составном приложении с PRISM 2.0 CAL, и это прекрасно. Я не думаю, что это существовало в PRISM 1.0?

Вам следует ознакомиться с «шаблонами и практиками: составной WPF и Silverlight».

http://www.codeplex.com/CompositeWPF/Wiki/View.aspx?title=Home

Он позволяет быстро начать работу с версиями одного и того же приложения WPF / Silvelight в одном решении. Также «Project Linker», который обновляет исходный код вашего приложения WPF, когда вы меняете код Silverlight (или наоборот) с помощью связывания. Его можно переопределить, если у вас есть код конкретной версии.

Примеры все еще немного грубоваты, но они могут дать вам представление о том, как вести свой проект.

HTH

Другие вопросы по теме