2012-04-02 12 views
11


Ho due classi di dati che contengono solo membri dati (nessuna funzione). Uno è CallTask ​​ l'altro è SmsTask. Queste due classi hanno alcune proprietà comuni come ID, Tel. Metto queste proprietà comuni in una classe di interfaccia separata e io uso questa classe di interfaccia nel mio progetto ogni volta che è appropriato.
Ora ho aggiunto un WCFService al mio progetto per condividere i dati tra client e server. Si consideri il seguente design di classe:
come contrassegnare un'interfaccia come DataContract in WCF

public interface IGsmTask : IComparable 
{ 
    string TaskID { get; set; } 
    string SessionID { get; set; } 
    string Tel { get; set; } 
} 

class CallTask : IGsmTask 
{ 
    #region IGsmTask Members 

    public string TaskID { get; set; } 

    public string SessionID { get; set; } 

    public string Tel { get; set; } 

    #endregion   
} 

class SmsTask : IGsmTask 
{ 
    #region IGsmTask Members 

    public string TaskID { get; set; } 

    public string SessionID { get; set; } 

    public string Tel { get; set; } 

    #endregion 

    public string SmsText { get; set; } 
} 

in questo disegno, voglio ospitare callTask, SmsTask, e IGsmTask ai clienti di utilizzare questi in methots servizi come il seguente;

[OperationContract] 
    public void AddTask(IGsmTask task) 
    { 

    } 

Ho provato a segnare [DataContract] su IGsmTask ma mi dà errore complition. Non c'è qualche methot che possa usare le interfacce come DataContracts? O come dovrei usare i tipi di KnownAttributes in questo synerio?
Grazie.

+1

interfaccia modifica alla classe – Reniuz

+0

Grazie Reniuz sembra che non posso usare le interfacce per questo scopo. – Fer

+1

WCF è un ** sistema basato su messaggi ** - il client invia un messaggio serializzato XML al server. In quanto tali, tali messaggi devono essere ** tipi concreti ** che possono essere serializzati in XML e rappresentati con uno schema XML. Le interfacce non possono essere serializzate in XML .... –

risposta

11

Per quanto ne so l'utilizzo di interfacce come datacontracts non è possibile. Puoi usare una classe base e aggiungere attributi knowntype sull'altro.

+0

ho pensato che ci sarebbe stata una metrica usando le interfacce come datacontracts. se non è possibile dovrò cambiare la mia interfaccia in una classe base. Grazie. – Fer

+1

Poiché la serializzazione si basa su istanze di oggetti, penso che non ci sia un modo diretto per farlo. – daryal

8

Fer: Tutto è possibile con il giusto design.

Se il problema è:

Una classe è un contratto di dati

& &

1 o più delle sue proprietà deve essere un'interfaccia ...

public interface ICustomInterface 
{ 
    int Property1 {get;set} 
} 

[DataContract] 
public class MyClass 
{ 
    [DataMember(Name="_myInterface")] 
    public ICustomInterface MyInterface {get;set;} 
} 

Il problema è che quando si verifica la de-serializzazione - Non c'è modo di trasformare i dati in una classe che implementa ICustomInterface.

La soluzione è creare una classe concreta che implementa l'interfaccia e lancia il getter/setter della proprietà pubblica (ovvero dell'interfaccia di tipo) in una proprietà privata della classe concreta.

public class CustomInterfaceImplementor: ICustomInterface 
{ 
    public int Property1 {get;set;} 
} 

[DataContract] 
public class MyClass 
{ 
    [DataMember(Name="_myInterface")] 
    private CustomInterfaceImplementor _MyInterface; 
    public ICustomInterface MyInterface 
    { 
      get {return (_MyInterface as ICustomInterface);} 
      set {_MyInterface = (value as CustomInterfaceImplementor);} 
    } 
}