12

Silverlight プロジェクトを完了したばかりなので、少しクリーンアップする時が来ました。コア ファイルを取得して、メインの Silverlight アプリから参照する別のプロジェクトに配置したいと考えています。これらのクラスの一部は WPF と互換性があり、Silverlight と WPF のコードをすべて 1 つのプロジェクトで使用できるようにしたいと考えています。私の理想的なソリューションは、複数の構成が可能な単一のプロジェクトです。そう、

構成: Silverlight は以下を生成します: Company.Controls.Silverlight.dll

構成: WPF は以下を生成します: Company.Controls.Wpf.dll

定義によって区切られた同じファイルに同じソースを含めることは可能ですか?

誰もこれを以前にやったことがありますか?

編集: MyCompany.Windows.Controls のようなプロジェクトごとにソリューションを作成しました。これには、MyCompany.Windows.Controls と MyCompany.Windows.Controls.Silverlight の 2 つのプロジェクトが含まれます。これらの 2 つのフォルダーに加えて、両方のプロジェクトで使用されるファイルを含む "Shared" フォルダーがあります。これまでのところうまくいきます:)

4

3 に答える 3

10

更新:ほとんどの場合、より簡単な方法があることを示しています。:-)

最初のステップは、条件付きコンパイルを使用して Silverlight 固有のコードを分離することです。(「デフォルト」のターゲットはWPFであると想定しています。)

次に、各プラットフォームのコードをコンパイルし、適切な定義とアセンブリ参照を設定するビルド スクリプトが必要です。

オープンソースの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 で開いてコンパイルすると、標準フレームワークに準拠します。参照は、Silverlight ではなく、.NET 3.5 および WPF 用です。前処理ディレクティブが「!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 になります。

于 2008-10-16T21:22:36.660 に答える
6

私は自分で試したことはありませんが (まだ Silverlight で遊ぶ時間を見つけようとしています)、2 つのプロジェクト (1 つは Silverlight を対象とし、もう 1 つは .NET 3.5 を対象とする) を持つ 1 つのソリューションを用意して、共通のクラス ファイルを各プロジェクトをリンクとして (プロジェクトを右クリックし、既存の項目を追加...、リンクとして追加)?

** 更新: Project Linker については、以下の Mark の回答を参照してください。PRISM 2.0 CAL を使用してマルチターゲット複合アプリケーションでこれを使用してきましたが、これは素晴らしいことです。これは PRISM 1.0 には存在しなかったと思いますか?

于 2008-10-17T02:57:02.727 に答える
3

「パターンとプラクティス:複合WPFとSilverlight」を確認する必要があります

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

1つのソリューションで同じアプリのWPF/Silvelightバージョンをすばやく開始できます。また、リンクを使用してSilverlightコードを変更した場合(またはその逆の場合)にWPFアプリのソースを更新する「プロジェクトリンカー」。バージョン固有のコードがある場合は、オーバーライドできます。

例はまだ端が少し荒いですが、それはあなたにあなたのプロジェクトをどのように進めるかについての考えを与えるかもしれません。

HTH

于 2008-11-12T23:17:17.827 に答える