2010-06-25 4 views
2

Je ce scénario:XmlInclude à (De) SERIALIZE Types hérités dans les assemblées séparées

namespace MyApp.Animals 
{ 
    public class Dog : MyApp.Categories.Canine 
    ... 

Je suis en train de linéariser/désérialiser la classe chien. Malheureusement, je ne peux pas utiliser l'attribut [XmlInclude], car en l'ajoutant à la classe parent (MyApp.Categories.Canine), j'ai besoin d'ajouter une référence à l'assembly dans lequel la classe parent existe (MyApp.Animals). Cependant, la classe enfant fait déjà référence à la classe parent en raison de l'héritage ... nous avons donc une référence circulaire.

Y a-t-il une meilleure façon d'y parvenir? Je peux contourner cela en sérialisant/désérialisant manuellement les propriétés qui existent sur la classe parent, et en effectuant la sérialisation sur l'enfant, mais ce n'est pas très élégant.

Espérant quelques meilleurs conseils ..

MISE À JOUR: Ajout à l'exemple en réponse au commentaire de John ci-dessous ...

Je n'ai pas un exemple complet de code (le code je travaille est massive et compliquée), mais le problème est que certaines des propriétés qui devraient être/sérialiser vers/depuis le xml sont contenues dans la classe parente, qui est dans un assemblage différent de la classe enfant. L'ajout des attributs XmlElement à la classe parent ne fonctionne pas car nous effectuons réellement la de/serialization sur la classe enfant, de sorte qu'elle n'invite pas au parent. Et nous ne pouvons pas le faire sur le parent parce que nous ne pouvons pas ajouter une référence à l'enfant (puisque l'enfant fait déjà référence au parent), donc le de/serialiser ne saura pas sur quel enfant agir.

Pour ajouter un niveau supplémentaire de complexité, l'objet que j'ai le problème est effectivement de/sérialisé dans le cadre d'une plus grande sérialisation, par la propriété suivante d'un objet parent:

[XmlElement("ShippingAddress")] 
    public Location ShippingAddress 
    { 
     get { return _shippingAddress; } 
     set { _shippingAddress = value; } 
    } 

Le Le problème est que le type d'emplacement ici est le type d'emplacement de l'enfant. Ainsi, seules les propriétés du type enfant obtiennent de/sérialisé ... toutes les propriétés du type parent (également appelées Location, mais dans un espace de noms differnet) ne le sont pas.

est-ce que cela le rend plus clair?

+0

Pouvez-vous s'il vous plaît montrer le code et le code XML résultant? Ce n'est pas clair pourquoi vous auriez besoin de 'XmlInclude'. –

+0

J'ai mis à jour mon message original .. – Jeeby

Répondre

1

XmlSerializer a un constructor qui prend dans un tableau de types appelés "extraTypes". Les types de ce tableau seront disponibles pendant la sérialisation et la désérialisation, comme si vous aviez ajouté des attributs XmlInclude.

var serializer = new XmlSerializer(typeof(Canine), new Type[] { typeof(Dog) }); 

Mise à jour: Cette approche fonctionne si votre Xml comprend un attribut xsi:type lorsque le type est différent de ce qui a été déclaré sur l'objet racine. Il semble que vous souhaitiez simplement toujours désérialiser cette propriété en tant que type différent. Dans ce cas, vous pouvez utiliser XmlAttributeOverrides pour remplacer les métadonnées sur les types d'origine. La construction du XmlSerializer comme ceci:

var overrides = new XmlAttributeOverrides(); 
var xmlAttributes = new XmlAttributes(); 
xmlAttributes.XmlElements.Add(new XmlElementAttribute("ShippingAddress", typeof(ITSM.Location))); 
overrides.Add(typeof(Order), "Location", xmlAttributes); 
var ser = new XmlSerializer(typeof(Order), overrides); 

aura le même effet que le remplacement des attributs sur la propriété Order.Location avec:

[XmlElement("ShippingAddress", typeof(ITSM.Location))] 
+0

ouais ..J'avais déjà essayé cela - n'a pas fonctionné. Je pense parce que j'appelle en fait la désérialisation sur un objet parent, pas l'objet avec lequel j'ai des problèmes: // Désérialise le XML reçu dans un objet Order Type [] types = {typeof (commun. Emplacement), typeof (ITSM.Location)}; Ordre o = (Commander) EntityUtils.DeserializeObject (d.DocumentElement, types); – Jeeby

Questions connexes