Обновление: показывает, что почти всегда есть более простой способ. : -)
Первым шагом является использование условной компиляции для разделения кода Silverlight. (Я предполагаю, что ваша цель по умолчанию - WPF.)
Во-вторых, вам понадобится скрипт сборки, который скомпилирует код для каждой платформы, установив соответствующие определения и ссылки на сборки.
Взгляните на открытый исходный код Caliburn project . Это делает все это.
Вот пример из класса 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".
В вашем скрипте сборки (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.