Interfacce da utilizzare con WCF: consigli?
Senza scendere nei dettagli di WCF, è chiaro come client e server comunichino fra loro attraverso un’interfaccia. Supponiamo di aver definito un’interfaccia IFatturazione che espone i seguenti membri pubblici:
[ServiceContract()] public interface IFatturazione { [OperationContract] int GetImportoFattura(string denominazione); [OperationContract] string GetXmlArticolo(string Codice); [OperationContract] string GetXmlCliente(string Codice); [OperationContract] string GetNuovoNumeroFattura(); [OperationContract] bool SalvaFattura(string xmlFattura); }
ServiceContract ed OperationContract sono due attributi che fanno parte del mondo WCF per identificare quando una certa interfaccia funge da contratto per un servizio, e quali sono i metodi che devono essere esposti attraverso la comunicazione. Pensandoci bene oggi pomeriggio, sono arrivato ad un’altra possibile definizione dell’interfaccia, cioè questa:
[ServiceContract()] public interface IFatturazione { [OperationContract] int GetImportoFattura(string denominazione); [OperationContract] Articolo GetArticolo(string Codice); [OperationContract] Cliente GetCliente(string Codice); [OperationContract] string GetNuovoNumeroFattura(); [OperationContract] bool SalvaFattura(Fattura fattura); }
La grande differenza fra le due è che la prima espone tipi base del .NET Framework: i metodi ritornano tipi come int, string e bool. I parametri di input dei metodi sono tutti di tipo string. La seconda invece è un po’ più consistente e forte per il domain model sul quale sto sviluppando: i metodi ritornano oggetti come Articolo, Cliente oppure prendono in input istanze di Fatture. Ad una prima analisi, dal mio punto di vista la seconda interfaccia sembrava migliore, però mi ha obbligato ad effettuare alcune operazioni:
- I tipi che devono essere trasmessi (Articolo, Cliente e Fattura) devono essere decorati con l’attributo DataContract. Cosa che non è sempre possibile, per esempio quando non disponiamo del sorgente dei tipi appena citati. Nel mio caso non è così, però, come ragionamento ci sta.
- La prima interfaccia mi dà l’impressione di essere più interoperabile. D’altra parte, non fa altro che mandare avanti ed indietro stringhe in XML, o comunque di ritornarmi tioi semplici. La secondo no. Ditemi se sbaglio.
Alla fine ho scelto la prima implementazione di IFatturazione.
Sul server ho messo del codice che serializza oggetti e li restituisce come XML al client. Per esempio, se il client esegue il metodo GetXmlCliente passando un certo codice, viene creata un’istanza dell’oggetto, i valori delle proprietà vengono lette da database. Poi l’oggetto viene serializzato in uno StringWriter e restituito al client. Ecco il metodo che fa da helper a questa funzionalità:
static string getSerializedObject(Entity instance) { XmlSerializer ser = new XmlSerializer(instance.GetType()); StringWriter output = new StringWriter(); ser.Serialize(output, instance); output.Flush(); output.Close(); return(output.ToString()); }
Sul client c’è del codice che fa l’esatto opposto, cioè da una stringa XML deserializzo per ottenere l’istanza dell’oggetto. Vero che così facendo ho aggiunto un po’ elaborazione aggiuntiva, ma ho preferito fare così. Se anche voi sviluppate con WCF, mi piacerebbe sapere cosa ne pensate, perchè sicuramente siete passati anche voi da una situazione di questo tipo. Come l’avete risolta? Perchè?
Technorati Tags: .NET Framework programming WCF interface