2

I am working on a program that uses Nhibernate to persist objects, and Xml Serialization to import and export data. I can't use the same properties for collections as, for example, Nhibernate needs them to be Ilists, because it has it's own implementation of that interface, and I can't Serialize interfaces. But as I need both properties to be synchronized, I thought I could use two different properties for the same Field. The properties will be according to what I need for each framework, and they will update the Field accrodingly.

So, I have the following field:

private IList<Modulo> modulos;

And the following properties:

 [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);
            }

        }

The first one is working perfectly, being quite standard, but I have some problems with the second one. The get is working great as I am having no problems Serializing objects (meaning it correctly takes the info from the field). But when I need to Deserialize, it is not getting all the info. The debugger says that after the Deserialization, the field is not updated (null) and the Property is empty (Count = 0).

The obvious solution would be using two unrelated properties, one for each framework, and passing the information manually when needed. But the class structure is quite complicated and I think there should be a more simple way to do this.

Any Idea how I can modify my property for it to do what I want? Any help will be appreciated.

  • Are you lazy loading the collection? If so, deserializing the XML won't load it, thus giving a count of 0. The easiest although verbose method would be to create a wrapper class specifically for the web, instead of passing NHibernate objects, which is just a bad idea. – rebelliard Aug 22 '10 at 08:19

1 Answers1

1

The short answer is that you cant.

Typically you would create a DTO ( Data transfer object ) separate from your NHibernate objects. For example:

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

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

On your DTO object you only put the properties that you intend to serialize. You than create a DTO from your domain model when you need to serialize one.

There is a great little library called automapper that makes mapping from your domain objects to your dto's pretty straight forward. See: http://automapper.codeplex.com/

Here is an example of a person class that supports mapping to the above DTO.

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;
    }
}
Jared Kells
  • 6,771
  • 4
  • 38
  • 43