Подтвердить что ты не робот

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

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

Конфигурация: Silverlight будет генерировать: Company.Controls.Silverlight.dll

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Взгляните на open-source проект Caliburn. Он делает все это.

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

    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".

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

<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.

Ответ 3

Вы должны проверить "шаблоны и методы: Composite WPF и Silverlight"

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

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

Примеры по-прежнему немного шероховаты по краям, но это может дать вам представление о том, как продвигаться по вашему проекту.

НТН