6
votes

WCF: La sérialisation d'une interface générique est-elle possible?

J'essaie de mettre en œuvre un contrat de service contenant une méthode qui prend une interface générique et que l'interface générique elle-même reçoit un paramètre d'interface. J'ai décoré l'interface de service avec ServiceknownType, j'ai décoré la mise en œuvre du service avec une personne connue régulière et j'ai décoré la mise en œuvre de Datacontract avec une personne connue régulière: xxx

pour l'enregistrement, j'ai lot Parce qu'il semble que vous puissiez seulement exprimer un type connu pour un type générique une fois - il semble émettre de Batchofanype, mais je ne sais pas comment gérer cela.

L'exception que je reçois est "Ajouter Tous les types non connus de manière statique à la liste des types connus - par exemple, à l'aide de l'attribut connu deTypeAttribute ou en les ajoutant à la liste des types connus passés à DatacontractSerializer. "

Y a-t-il quelque chose d'évident que je fais mal? Les interfaces génériques d'interfaces ne sont-elles pas prises en charge? Pour le dossier, je suis sur C # 2.0 et .NET 3.0 pour ce projet.


0 commentaires

4 Réponses :


2
votes

WCF est un système basé sur un message SOA - il peut envoyer n'importe quoi sur le fil du format XML sérialisé pouvant être exprimé en schéma XML.

Malheureusement, le schéma XML ne connaît rien ni des interfaces ni des génériques, donc non - vous ne pouvez pas génériquement sérialiser ceux-ci - vous devez utiliser des types de béton.


5 commentaires

WCF comprend assez les génériques pour les sérialiser (je l'ai fait). Votre point sur les interfaces est correct.


@RQDQ Avez-vous un endroit pour montrer cela? Un blog, un article de codeProject ou quelque chose? J'adore voir ça!


@RQDQ: En fait, ce n'est pas entièrement correct, imo. Bien que l'interface elle-même ne puisse pas être sérialisée, le type de béton utilisé peut . La partie «délicate» est la désérialisation, car elle doit savoir quel type concret à instanecter. Cependant, suffisamment d'informations sont incluses dans les données sérialisées pour faire exactement cela.


Je viens de poster un certain code qui sérialise un verre générique sur le fil.


@Thorarin - vous êtes correct. Je viens de mettre en place une reproduction (accordée dans le cadre 4.0) qui sérialisise une interface correctement des deux sens. Certes, le client généré par VS expose les opérations comme objet de type au lieu d'une interface ou du type de base.



1
votes

Vous ne pouvez pas sérialiser une interface. Une interface définit simplement le contrat, pas l'objet. Je suppose que la seule exception à ceci est l'interface iséritallissable.


2 commentaires

Lorsque vous êtes "Serializing Iséralisable ", vous n'êtes vraiment pas, vraiment. iserializable est une interface utilisée pour sérialiser autre chose.


@John. Vous avez raison. Vous n'êtes toujours pas vraiment sérialisée de l'interface, il suffit d'accepter un contrat utilisé pour sérialiser les objets qui mettent en œuvre isérialisable. Je viens d'ajouter cela pour la complétude.



12
votes

Vous pouvez utiliser des interfaces dans les définitions de contrat de service si vous voulez vraiment, tant que vous incluez les types connus que vous le faites (avec un léger ajustement, voir ci-dessous).

Apparemment, en utilisant une interface lorsque le paramètre de type générique prend un pont trop loin pour C # 3.0. J'ai changé l'attribut de type connu sur xxx

ce qui le rend le fonctionnement, à un point. La sérialisation et la désérialisation elle-même fonctionneront, mais vous êtes confronté à cette exception:

Impossible de lancer l'objet de type 'Batch`1 [Commande]' Tapez 'iBatch`1 [ICOMMAND]' '.

Pour cette distribution au travail, vous avez besoin d'un soutien linguistique pour la covariance de type générique, quelque chose qui a été introduit en C # 4.0. Pour qu'il fonctionne en C # 4.0, vous devez ajouter un modificateur de variance: xxx

alors cela fonctionne parfaitement ... Malheureusement, vous n'utilisez pas c # 4.0.

Une dernière chose à propos de l'utilisation d'interfaces dans votre contrat de service: Si vous générez une référence de service à partir d'eux, il saisira tous les paramètres d'interface comme objet , en raison de l'interface d'origine. le type ne fait pas partie des métadonnées. Vous pouvez partager des contrats via une référence d'assemblage ou refacteur manuellement le proxy généré pour le réparer, mais dans l'ensemble, à l'aide d'interfaces avec WCF, c'est probablement plus de problèmes que cela ne vaut.


1 commentaires

Ouais, j'ai édité dans la plate-forme que j'utilise quand j'ai pensé à la covariance en C # 4.0. Oh, pour mettre à niveau.



1
votes

Les génériques peuvent être sérialisés, mais avec certaines limitations. Par exemple, étant donné le contrat de données: xxx pré>

et le contrat de service: p> xxx pré>

et la mise en œuvre du service: p>

[System.Runtime.Serialization.DataMemberAttribute()]
public string Value 
{ 
   get {...} 
   set {...} 
}


0 commentaires