2010-08-22 8 views
2

Je travaille sur un programme qui utilise Nhibernate pour persister des objets, et Xml Serialization pour importer et exporter des données. Je ne peux pas utiliser les mêmes propriétés pour les collections que, par exemple, Nhibernate a besoin d'être Ilists, car il a sa propre implémentation de cette interface, et je ne peux pas sérialiser les interfaces. Mais comme j'ai besoin de synchroniser les deux propriétés, j'ai pensé que je pourrais utiliser deux propriétés différentes pour le même champ. Les propriétés seront en fonction de ce dont j'ai besoin pour chaque framework, et ils mettront à jour le champ de façon permanente.C#, problème de mélange Xml Sérialisation avec Nhibernate

Donc, j'ai le champ suivant:

private IList<Modulo> modulos; 

Et les propriétés suivantes:

[XmlIgnore] 
     public virtual IList<Modulo> Modulos 
     { 
      get { return modulos; } 
      set { modulos = value; } 
     } 

     [XmlArray] 
     [XmlArrayItem(typeof(Modulo))] 
     public virtual ArrayList XmlModulos 
     { 
      get 
      { 
       if (modulos == null) return new ArrayList(); 
       var aux = new ArrayList(); 
       foreach (Modulo m in modulos) 
        aux.Add(m); 
       return aux; 
      } 
      set 
      { 
       modulos = new List<Modulo>(); 
       foreach (object o in value) 
        modulos.Add((Modulo)o); 
      } 

     } 

Le premier fonctionne parfaitement, étant tout à fait standard, mais j'ai quelques problèmes avec la deuxième un. Le get fonctionne très bien car je n'ai aucun problème Sérialiser les objets (ce qui signifie qu'il prend correctement les informations du terrain). Mais quand j'ai besoin de désérialiser, il ne reçoit pas toutes les infos. Le débogueur dit qu'après la désérialisation, le champ n'est pas mis à jour (null) et la propriété est vide (Count = 0).

La solution évidente serait d'utiliser deux propriétés non liées, une pour chaque infrastructure, et de transmettre les informations manuellement si nécessaire. Mais la structure des classes est assez compliquée et je pense qu'il devrait y avoir une façon plus simple de faire cela.

Une idée comment je peux modifier ma propriété pour qu'elle fasse ce que je veux? Toute aide serait appréciée.

+0

Êtes-vous paresseux en chargeant la collection? Si tel est le cas, désérialiser le XML ne le chargera pas, donnant ainsi un compte de 0. La méthode la plus simple mais la plus verbeuse serait de créer une classe wrapper spécifiquement pour le web, au lieu de passer NHibernate, ce qui est une mauvaise idée. – rebelliard

Répondre

1

La réponse courte est que vous ne pouvez pas.

Généralement, vous créez un DTO (objet de transfert de données) distinct de vos objets NHibernate. Par exemple:

public class PersonDto 
    { 
     [XmlAttribute(AttributeName = "person-id")] 
     public int Id { get; set; } 

     [XmlAttribute(AttributeName = "person-name")] 
     public string Name{ get; set; } 
    } 

Sur votre objet DTO, vous ne mettez que les propriétés que vous avez l'intention de sérialiser. Vous créez un DTO à partir de votre modèle de domaine lorsque vous devez sérialiser un.

Il existe une petite bibliothèque appelée automapper qui permet de mapper les objets de votre domaine vers vos dto. Voir: http://automapper.codeplex.com/

Voici un exemple de classe de personne qui prend en charge le mappage vers le DTO ci-dessus.

public class Person 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 

    static Person() 
    { 
     Mapper.CreateMap<PersonDto, Person>(); 
     Mapper.CreateMap<Person, PersonDto>(); 
    } 

    public Person(PersonDto dto) 
    { 
     Mapper.Map<PersonDto, Person>(dto, this); 
    } 

    public PersonDto ToPersonDto() 
    { 
     var dto = new PersonDto(); 
     Mapper.Map<Person, PersonDto>(this, dto); 
     return dto; 
    } 
}