さまざまなプラットフォームでのコードの再利用と互換性は、最近ではかなり話題の問題です。 さらに、MSFTは最近、さまざまなプラットフォームとプログラミング言語の開発者を喜ばせようとしています。 そのため、おそらく、ユニバーサルWindowsプラットフォームの機能により、複数のタイプのライブラリを使用できます。 どのライブラリ、UWPアプリケーションでそれらをどのように、そしてなぜ使用できるかについての猫の下。
クラスライブラリ-Windowsストアアプリケーションのクラスライブラリ
Windowsストアアプリで使用可能なクラスとメソッドを備えた.Netライブラリ。 .Net言語で記述されたUWPアプリケーションでのみ使用できます。 つまり、たとえばJavaScriptは消えます。
アプリケーションは、UWPクラスの通常の.Netクラスライブラリを使用できないことに注意してください。
.NETコードをWindowsストアアプリケーション用の.Netに変換するときに行う必要のある相違点と変更点のリストは、
.NET for Windowsストアアプリの概要にあります。ある程度の類似点はありますが、多くの変更点と相違点があります。 多くの場合、名前空間のみが異なり、メソッドとプロパティは同じままです。 これは、既存のコードの移植の便宜のために行われます。 もちろん、すべての.Net機能がWindowsストアアプリケーションで利用できるわけではありません。 一部はセキュリティ上の理由、またはUWPで概念的に複製したくないためです。
ポータブルクラスライブラリ-PCL(ポータブルクラスライブラリ)
これらのライブラリでは、選択したプラットフォームに応じて、機能の特定の部分を使用できます。 プロジェクトの作成時にターゲットプラットフォームが選択されます
これらのターゲットプラットフォームは、プロジェクトプロパティでいつでも変更できます。
コードは複数のプラットフォームに対応するため、すべてのタイプとメンバーは選択したプラットフォームに存在している必要があり、プラットフォーム固有のものを含めることはできません。 また、非推奨または例外のフラグを立てる必要もありません。
Windowsランタイムコンポーネント
WinRTプラットフォーム言語のいずれかで使用できるコンポーネント。 コンポーネントの拡張子は.winmdで終わります。 ただし、混乱させないでください。コンポーネントは非常に頻繁にライブラリとして使用され、含まれるメタデータにより、すべてのWinRT言語で動作します。 これが主なプラスです。
たとえば、作成したクラスライブラリプロジェクトで、プロパティを使用して、構築の結果としてランタイムコンポーネントを選択する方法を示します。
ただし、この場合、言語間の互換性が失われ、C#とVBからのみそのようなライブラリを操作できるようになります。
ランタイムコンポーネントはCOMに基づいています。 マネージ言語でネイティブのWindowsランタイムコンポーネントを作成できることがわかりました。
すべてのWinRT言語は、独自のデータ型を使用します。 ただし、ランタイムコンポーネントでは、データを統一する必要があります。
プリミティブ型は、すべての言語でほぼ類似しています。 主にJavaScriptのみが異なります。
マッピングテーブルはリンクで見つけることができます:
Windowsランタイムの基本データ型Windowsランタイムタイプの.NET FrameworkマッピングWinRT言語は異なるため、いくつかの共通点に到達する必要がある場合があります。 たとえば、.NetおよびJavaScriptアプリケーションでは、文字列は不変であり、C ++では変更可能です。 Windowsランタイムコンポーネントでは、文字列は不変です。
制限/ルール:
- 公開アイテムは封印する必要があります。
- パブリッククラスまたはパブリックインターフェイスをジェネリックにすることや、WinRT以外のインターフェイスを実装することはできません。
- パブリッククラスはWinRT型から派生できません。
- すべてのフィールド、パラメーター、およびパブリックメンバーの戻り値は、Windowsランタイムタイプである必要があります。
- ルート名前空間はアセンブリの名前と一致する必要があり、「Windows」で開始することはできません。
- WRCはポリモーフィズムをサポートしていません
- Windowsランタイムのメソッドはオーバーロードできますが、同じ数のパラメーターの場合は、属性でマークする必要があります。 公式の例:
public string OverloadExample(string s) { return s; } [Windows.Foundation.Metadata.DefaultOverload()] public int OverloadExample(int x) { return x; }
Windowsストアアプリケーションのクラスライブラリには制限が最も少ないため、.Net言語のアプリケーションがある場合は、このライブラリを選択することをお勧めします。
実際の例:
UWPアプリケーションがWebViewを使用してWebサイトを表示する場合、JavaScriptロードされたWebページからアクセスできるアプリケーションのクラスを使用する機会があります。
また、このクラスはWindowsランタイムコンポーネント内に配置する必要があります。 これは、言語間の互換性が必要な場所です。
コンポーネントが作成され、WebViewページを含むメインプロジェクトからリンクが作成されます。 コンポーネント内で、1つまたは複数のパブリッククラスを[AllowForWeb]属性でマークできます。 そのようなクラスのすべてのパブリックメソッドは、WebViewページにロードされたJavaScriptからアクセスできます。
AddWebAllowedObjectメソッドを使用してページでナビゲーションを開始するときにのみ、このクラスを追加する必要があります。
はい、もちろん、JSコードでwindow.external.notifyを使用するオプションがありますが、これらの呼び出しが信頼できるhttpsサイトからのみ許可される特定のセキュリティ制限があります。
少し繰り返して、MSDNで例を複製します。 SomeValueFromJSメソッドをコンポーネントのWinRTクラスに追加します
using Windows.Foundation.Metadata; namespace MyRuntimeComponent { [AllowForWeb] public sealed class MyNativeClass { public void SomeValueFromJS(string value) { } } }
XAMLでWebViewを追加します
<WebView x:Name="webView" Source="https:// www.contoso.com/script.htm" NavigationStarting="webView_NavigationStarting"/>
ナビゲーションの開始時に、クラスをJavaScriptに埋め込みます
private void webView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) { if (args.Uri.Host == "www.contoso.com") { webView.AddWebAllowedObject("csharpclass", new MyNativeClass()); } }
これで、JSコードからこのメソッドを次のように呼び出すことができます。
csharpclass.nativeMethod("hello!");
すべてうまくいくように見えますが、残念なことに、WebViewを使用してページにデータを転送する必要がある場合があります。 WebViewを使用したプロジェクトは既にWinRTコンポーネントを参照しているため、循環依存関係のためにバックリンクを追加できません。 WRCの制限により、特定のオプションを使用することはできません。 解決策として、Windowsストアアプリケーション用のクラスライブラリの形式で中間層を作成できます。これにより、制限がはるかに少なくなります。 BridgeClassと呼ばれるクラスを含むこのライブラリへのリンクは、メインプロジェクトとWindowsランタイムコンポーネントプロジェクトの両方から作成できます。
Opportunities .Netでは、手頃な価格のイベントを作成できます
public static event Action<string>
メインプロジェクトのイベントにサブスクライブします。 コードを見てみましょう。 BridgeClassクラスコード:
public class BridgeClass { public static event Action<string> MessageReceived; public static void Broadcast(string message) { if (MessageReceived != null) MessageReceived(message); } }
メインプロジェクトのWebViewを含むページのコードビハインドで、イベントをサブスクライブします。
BridgeClass.MessageReceived += ShowMessage;
そして実装します:
void ShowMessage(string msg) { }
これで、JSで使用可能なメソッドから、値をC#に渡すことができます。
public void SomeValueFromJS(string value) { BridgeClass.Broadcast(value); }