2014-05-20 1 views
1

Je cherche la meilleure méthode pour cela. J'ai une série de types de données que je veux retourner dans la WCF, sous une méthode. C'est pourquoi j'ai une MarkerInterface, de sorte que je n'ai pas besoin de 100s de ServiceContracts/Methods pour simplement transformer les données. La partie malheureuse est, tous les DataContracts (tels que currentbatch) sont tous uniques, ils ont leur ensemble unique de propriétés. La raison pour laquelle j'ai un Transformer est qu'ils ont tous besoin d'une sorte de Transformation de Données basée sur l'ensemble de données.Utilisation d'une interface comme contrat de données pour le service WCF

L'interface du transformateur est la suivante:

public interface IDataTransformer 
{ 
    IMarkerInterface Transform(DataSet inDataSet_); 
} 

Puis-je avoir une bibliothèque de transformateur pour chaque DataContract (que je vais expliquer ci-dessous)

public class CurrentBatch_Transformer : IDataTransformer 
{ 
} 

Ceci est un des nombreux DataContracts je vais avoir, que mettre en œuvre IMarkerInterface.

[DataContract] 
public class CurrentBatch : IMarkerInterface 
{ 
    [DataMember] 
    public string GroupName { get; set; } 

    [DataMember] 
    public bool FlagLocked { get; set; } 
} 

Donc, parce que j'ai une IMarkerInterface; Je peux tout placer dans une méthode (GetDataUsingDataContract), et prendre dans leur transformateur respectif et un DataSet.

public IMarkerInterface GetDataUsingDataContract(IDataTransformer composite, DataSet inData_) 
    { 
     if (composite == null) 
     { 
      throw new ArgumentNullException("composite"); 
     } 

     return composite.Transform(inData_); 
    } 

Encore une fois, mes questions sont les suivantes:

1) Est-ce une bonne pratique? Si ce n'est pas le cas pourquoi, et y a-t-il une meilleure façon de le faire? 2) L'interface sera-t-elle sérialisée pendant la sérialisation de la WCF? (Je ne veux pas que cela soit sérialisé, mais cela ne me dérangerait pas si c'était le cas).

+0

Interfaces ne reçoivent aucun numéro de série - ils ont aucune donnée et donc il n'y a rien * à * serialize. Le client le verra comme un 'Object' (en langage .NET). Donc, si vous êtes un client .NET, il devra savoir comment lancer le 'Object' au bon type. – Tim

+0

@Tim est-il sûr de dire alors que le client ne saurait même pas qu'une interface a été implémentée sur la classe? – Ramie

+0

Oui. Selon la langue, le client peut même ne pas avoir le concept d'une «classe». À moins, bien sûr, que le client ait accès à l'assemblage dans lequel se trouvent les contrats de données (auquel cas ce serait le cas).NET) - alors il faudrait savoir que la classe a implémenté une interface. – Tim

Répondre

2

Oui, c'est une solution acceptable, mais vous devez informer WCF du type de types que vous allez utiliser, car il devrait former un document WSDL. Vous pouvez utiliser l'attribut ServiceKnownType pour ServiceContract, KnownType pour le contrat de données ou ajouter des types connus dans config.

Voici quelques exemples:

  1. ServiceContract:

    [ServiceKnownType("GetKnownTypes", typeof(Helper))] 
    [ServiceContract()] 
    public interface IService 
    { 
        [OperationContract] 
        IMarkerInterface GetMarker(); 
    } 
    
    static class Helper 
    { 
        static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider) 
        { 
         return new Type[] { typeof(CurrentBatch) }; 
        } 
    } 
    
  2. KnownType:

    [DataContract] 
    [KnownType("GetKnownType")] //there are few option of usage, you can apply for one concrete class: [KnownType(typeof(InheritedClass))] 
    public class BaseClass 
    { 
    
        private static Type[] GetKnownType() 
        { 
         return return new Type[] { typeof(InheritedClass) };; 
        } 
    } 
    
  3. fichier de configuration:

    <system.runtime.serialization> 
        <dataContractSerializer> 
        <declaredTypes> 
         <add type="MyProject.IMarkerInterface, MyProjectAssembly"> 
         <knownType type="MyProject.CurrentBatch, MyProjectAssembly"/> 
         </add> 
        </declaredTypes> 
        </dataContractSerializer> 
    </system.runtime.serialization> 
    
Questions connexes