Domanda

Ho un servizio WCF ospitato in IIS. L'intenzione è per i clienti di effettuare una chiamata e ricevere una classe personalizzata definita in un altro progetto / dll. Ho generato un client di servizio utilizzando svcutil.exe. Il problema è che questo client generato automaticamente contiene una nuova definizione parziale / proxy per la classe che sto tentando di restituire dal servizio. Ora genera un errore di conversione tra la mia classe personalizzata originale e la nuova definizione parziale al momento della compilazione. Quindi, come si restituiscono i tipi definiti dall'utente da un servizio WCF? Consiglio apprezzato.

È stato utile?

Soluzione

Solo al secondo Yossi's / I pensieri di Rich :

  • sì, è possibile aggiungere un riferimento alla dll condivisa (anziché utilizzare la classe proxy generata)
  • sì, vanifica molte delle intenzioni dei contratti di dati e se si verifica qualsiasi tipo di serializzazione personalizzata, potresti avere problemi ad estendere il tuo servizio

Ho già percorso questa strada prima, e in qualche modo vorrei non averlo fatto. Re estensibilità / serializzazione personalizzata - devi essere molto attento. Un po 'più semplice se utilizzi un serializzatore pre-roll come protobuf-net ( che può integrarsi direttamente in WCF e che è stato progettato pensando all'estensibilità), ma non facile.

In realtà, un vantaggio della condivisione delle classi è che rende un po 'più facile il test: dato che hai lo stesso IFoo ovunque, puoi deridere quel IFoo con ragionevoli possibilità di successo. È più difficile deridere quando viene coinvolto il proxy (quando si cambiano più parti mobili tra il codice di test e il codice di produzione).

Altri suggerimenti

Se il tipo che si desidera restituire dalla chiamata di servizio non è contrassegnato come DataContract , non sarà possibile restituirlo da WCF senza fornire una copia dello stesso assembly al client applicazione.

using System;
using System.ServiceModel;

[ServiceContract]
interface IService
{
    [OperationContract]
    TimeSpan GetTimeSpan();
}

class Service : IService
{
    public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
}

Perché allora funziona il codice precedente? Funziona perché entrambi i lati della chiamata di servizio hanno System.dll , quindi entrambi conoscono il tipo System.TimeSpan che è il tipo restituito di OperationContract GetTimeSpan ( ) .

Ecco un esempio che utilizza un DataContract :

using System;
using System.ServiceModel;
using System.Runtime.Serialization;

[ServiceContract]
interface IService
{
    [OperationContract]
    Contract GetContract();
}

[DataContract]
class Contract
{
    [DataMember]
    public String MyProperty { get; set; }
}

class Service : IService
{
    public Contract GetContract() { return new Contract(); }
}

Ora hai fornito gli attributi di serializzazione a una classe che hai definito ( Contratto ) - questo ti permetterà di usare svcutil.exe per creare classi proxy nella tua applicazione client che verrà serializzato e inviato al servizio WCF.

Ora, se si desidera restituire un tipo che non sia un DataContract , è necessario fornire una copia dell'assembly contenente quel tipo all'applicazione client.

Una delle cose che dovranno accadere è che l'utente deve configurare il riferimento al servizio per utilizzare i tipi dalla DLL anziché la classe definita dal proxy - http://msdn.microsoft.com/en-us/library/bb628653.aspx

Abbiamo percorso questo percorso in passato, e in effetti il ??problema è che, naturalmente, si tratta di due classi diverse, quindi dovrai seguire il link fornito da @Rich Reuter;

Tuttavia, abbiamo imparato a fondo perché questa è una cattiva pratica in quanto risale al terzo principio dello schema e del contratto di condivisione dei servizi SOA, non di classe.

Ovviamente il problema non sta semplicemente seguendo una "regola". stabilito da qualcuno ad un certo punto, ma che c'erano grandi ragioni per suggerire questo - abbiamo imparato che il prezzo di un così stretto accoppiamento tra il servizio e il cliente significa che è molto difficile rilasciare entrambi - se il servizio deve aggiungere un altro campo di quella classe, per servire un altro client - il primo client potrebbe essere interessato; se il servizio deve cambiare qualcosa nella definizione di quella classe (per servire un altro client) - il primo client sarà nuovamente interessato e viceversa - il client potrebbe influenzare il ciclo di vita del servizio.

Nei grandi progetti questo diventa rapidamente un enorme onere di manutenzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top