ChannelFactory<T>
ha un metodo virtuale CreateChannel()
. Se non viene sovrascritto, utilizza la generazione del codice dinamico, che non riesce su MonoTouch.
La soluzione è sovrascriverla e fornire la propria implementazione in fase di compilazione.
Di seguito è una mia vecchia implementazione del servizio che almeno ha funzionato su MonoTouch. L'ho diviso in 2 classi parziali: il primo è stato collegato in tutte le build, il secondo solo nelle build iOS (consentendo al meccanismo di generazione dinamica di funzionare ancora su Windows).
L'ho rimosso per contenere solo 1 chiamata di servizio.
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
che esegue le chiamate tramite riflessione)
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);
}
}
}
EDIT: Ho appena provato questo con l'ultima MT (5.2) - Non ha più bisogno di tutto quel piatto di caldaia extra che avevo lì prima, solo l'override di CreateChannel(). Ho ripulito il codice di esempio per abbinarlo.
EDIT2: ho aggiunto un'implementazione del metodo asincrono.
grazie per la condivisione, ci provo ora. – BlueSky
La tua soluzione ha successo, grazie. – BlueSky
Qui dice che non riesce a trovare la classe ChannelBase. E non vedo come posso usarlo con metodi asincroni. Grazie! – cheeesus