困っていること
Xamarin.Forms(PCL)でWCFアクセスを行う場合のプロジェクト構成を、どうすべきかわからず困っています。
(ここではWCFを問題にしていますが、これに限った話ではなく、プロファイルによるAPIの制限のため必要なクラスが呼べないという問題です。)
詳細
(前提:ここでは、ソリューション内に ViewModelプロジェクト(PCL)、Androidプロジェクト、iOSプロジェクトが存在するとしてください。)
(また、ソリューションのベースはPrism Template Packを使用して作成しています。)
以下のページを参考に、XamarinのソリューションからWCFアクセスを行う処理を作成しています。
Walkthrough - Working with WCF
この解説では、ソリューション内で
System.Runtime.Serialization
,System.ServiceModel
,System.ServiceModel.Web
をAndroidプロジェクトの参照に追加HelloWorldService.cs
をAndroidプロジェクトに作成System.Runtime.Serialization
,System.ServiceModel
,System.ServiceModel.Web
をiOSプロジェクトの参照に追加HelloWorldService.cs
(Androidプロジェクトに置いたファイルのコピー) をiOSプロジェクトに作成
ということをしています。
ここで問題があります。
それは、ViewModel プロジェクトで HelloWorldService.cs
に定義されたクラスを使用できないことです。
(通常はViewModelからAndroid/iOSプロジェクトを参照することはしないと思っています)
HelloWorldService
の中では、System.Runtime.Serialization
, System.ServiceModel
, System.ServiceModel.Web
を使用しています。
(プロファイルにもよるかもしれませんが)PCL(ViewModel)からは System.Runtime.Serialization
, System.ServiceModel
, System.ServiceModel.Web
を呼ぶことができません。
ですから、仕方なく HelloWorldService
をAndroid/iOSプロジェクトに配置しているのだろうと思います。
HelloWorldService.cs
の中には通常複数のクラスが定義されており、そのクラスの一部をPCL(ViewModel)で使いたいという要求があります。
(例えばクライアント-サーバ間のデータのやりとりに使用する複雑なクラスが定義されており、これをViewModelで再定義するのは避けたいです)
しかしながらPCLからHelloWorldService
を参照することができないため困っています。
このような問題を解決する良い方法はないでしょうか。
(そもそも、内容が全く同じHelloWorldService.csを2つ用意する、という時点で気持ち悪さがあります。)
追記
ちなみに、プロファイルの制限がきついからViewModelからSystem.ServiceModelなどが参照できないのでは?と思い、プロジェクトのターゲット設定で「ASP.NET Core 1.0」を外してみたところ、
型 'Object' は、参照されていないアセンブリに定義されています。アセンブリ 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' に参照を追加する必要があります。
というエラーが、Prismが使われているクラスのあちこちで発生するようになってしまいました。
(例えばViewModelのファイルで public class MainPageViewModel : BindableBase, INavigationAware
← BindableBase の部分でエラーが出ます)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
(ここではWCFを問題にしていますが、これに限った話ではなく、プロファイルによるAPIの制限のため必要なクラスが呼べないという問題です。)
.NET Framework, Xamarin.Android(MonoDroid), Xamarin.iOS(MonoTouch) それぞれで同じクラスが用意されていても、PCL のプロファイルでそのクラスが定義されていなければ使用できない(=プラットフォーム固有のAndroidやiOSプロジェクト側での実装が必要になる)のは仕方のないことだと考えます。
ので、Xamarinに限らず.NET系での「複数プラットフォームに対応するライブラリ」は、PCLだけで完結できることは少なく、プラットフォーム固有の実装を含んだライブラリと共に利用されるのが一般的という認識です。
Plugins for Xamarin は、PCL+プラットフォーム固有のライブラリの組み合わせで作られているライブラリ群です。
考え方は、PCLプロジェクトでは、アプリケーションから使用されるAPIのインターフェースを定義し、そのインターフェースにAndroidプロジェクトやiOSプロジェクトにあるプラットフォーム固有の実装を「注入」します。
広義には DI(Dependency Injection=依存性の注入) と呼ばれるものですが、Plugins for Xamarin では「Bait & switch」というテクニックを使用してこれを実現しています。
その仕組みは、
- Plugins for Xamarinを作ろう! - ぴーさんログ
- 共有コードからネイティブ依存処理が使える!PCLを使ったXamarinライブラリ作成テクニック (フェンリル | デベロッパーズブログ)
で解説されています。
そもそも、内容が全く同じHelloWorldService.csを2つ用意する、という時点で気持ち悪さがあります。
これも同様の理由で仕方のないことと考えますが、Visual Studio のソースコードのリンク機能などでごまかすことはできるかと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.36%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/07/18 06:56 編集
今回のような場合、HelloWorldService.csをPCLとAndroid/iOSプロジェクトに置いたところで、
中身は同じでも異なるクラスとして認識され、Android側で生成されたHelloWorldServiceのインスタンスをPCLで使うことができないかと思います。
(そもそもSystem.Runtime.Serializationなどが呼べないのでPCLに配置すらできない)
そこで、 Plugins for Xamarin でHelloWorldServiceをNuGetパッケージ化してPCL/Android/iOSプロジェクトにインストールすることで問題を回避する必要がある、という認識で合っていますか?
2017/07/18 10:05
1. HelloWorldServiceLib(PCL)
2. HelloWorldServiceLib.Droid
3. HelloWorldServiceLib.iOS
となり、アプリプロジェクト(ViewModelなど)からは 1. を参照することになると思います。