ChannelFactory<T>
には仮想メソッドがありCreateChannel()
ます。これがオーバーライドされていない場合、MonoTouch で失敗する動的コード生成が使用されます。
解決策は、それをオーバーライドして、独自のコンパイル時の実装を提供することです。
以下は、少なくとも MonoTouch で動作していた私の古いサービスの実装です。私はそれを 2 つの部分クラスに分割しました。最初のクラスはすべてのビルドでリンクされ、2 番目は iOS ビルドでのみリンクされます (動的生成メカニズムが Windows で引き続き機能するようにします)。
1 つのサービス コールのみを含むように、それを削除しました。
TransactionService.cs:
public partial class TransactionService : ClientBase<IConsumerService>, IConsumerService
{
public TransactionService()
{
}
public TransactionService(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public TransactionService(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public TransactionService(string endpointConfigurationName, EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public TransactionService(Binding binding, EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public AccountBalanceResponse GetAccountBalance( AccountBalanceQuery query )
{
return Channel.GetAccountBalance( query );
}
}
TransactionService.iOS.cs:
ConsumerServiceClientChannel
リフレクションを介して呼び出しを実行します)
public partial class TransactionService
{
protected override IConsumerService CreateChannel()
{
return new ConsumerServiceClientChannel(this);
}
private class ConsumerServiceClientChannel : ChannelBase<IConsumerService>, IConsumerService
{
public ConsumerServiceClientChannel(System.ServiceModel.ClientBase<IConsumerService> client) :
base(client)
{
}
// Sync version
public AccountBalanceResponse GetAccountBalance(AccountBalanceQuery query)
{
object[] _args = new object[1];
_args[0] = query;
return (AccountBalanceResponse)base.Invoke("GetAccountBalance", _args);
}
// Async version
public IAsyncResult BeginGetAccountBalance(AccountBalanceQuery query, AsyncCallback callback, object asyncState )
{
object[] _args = new object[1];
_args[0] = query;
return (IAsyncResult)base.BeginInvoke("GetAccountBalance", _args, callback, asyncState );
}
public AccountBalanceResponse EndGetAccountBalance(IAsyncResult asyncResult)
{
object[] _args = new object[0];
return (AccountBalanceResponse)base.EndInvoke("GetAccountBalance", _args, asyncResult);
}
}
}
編集: これを最新の MT (5.2) でテストしたところです。以前にあった余分なボイラー プレートはすべて不要で、CreateChannel() オーバーライドだけが必要です。一致するようにサンプル コードをクリーンアップしました。
EDIT2:非同期メソッドの実装を追加しました。