Monotouch / WCF: come consumare il servizio wcf senza svcutil

Diventa monotouch compilare codice nativo, quindi ha alcune limitazioni come invocazione dynamic non è consentita.

Ma ho molta class in .net, che uso la dynamic ChannelFactory per invocare il servizio wcf: new ChannelFactory (myBinding, myEndpoint); Ora in monotouch dovrei usare slsvcutil per generare la class proxy wcf, ma lo slsvcutil genera un sacco di codice extra non necessario (enorme), e rende i consumatori difficili da testare, a causa dell’elevato accoppiamento con l’infrastruttura WCF attraverso la class ClientBase.

C’è una soluzione migliore tranne ChannelFactory? Preferisco scrivere il codice manualmente, avere più controllo su come vengono invocati i servizi come ChannelFactory.

==========

ChannelFactory factory = new ChannelFactory(binding, endpointAddress); return factory.CreateChannel(); 

// ==> Genera eccezione: MonoTouch non supporta la generazione di codice proxy dinamico. Sostituire questo metodo o il relativo chiamante per restituire un’istanza proxy client specifica

    ChannelFactory 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 di servizio che almeno era utilizzata per lavorare 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 dynamic di funzionare ancora su Windows).
    L’ho rimosso per contenere solo 1 chiamata di servizio.

    TransactionService.cs:

     public partial class TransactionService : ClientBase, 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 { public ConsumerServiceClientChannel(System.ServiceModel.ClientBase 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’ultimo 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.

    Penso che potresti avere dei termini confusi qui: ChannelFactory è un tipo generico , non dinamico .

    Secondo la documentazione di MonoTouch, anche se ci sono limitazioni al supporto di Generics in MonoTouch, ChannelFactory dovrebbe essere ok qui.

    Hai provato a usare ChannelFactory?