0

Can a POCO contain a constructor? Could you tell me if this class is correct? I also read that a POCO must have a parameterless constructor. Is that correct and why? If I accept this parameterless constructor, I'll have a problem with my read only Id property. For me, it seems logical that if this property must be read-only, then the only way to initialize it is in the constructor.

[DataContract]
public class MembershipUser
{
    public MembershipUser(Guid idValue)
    {
        this.Id = idValue;
    }

    [DataMember]
    public virtual readonly Guid Id { get; set; }

    [DataMember]
    public virtual string UserName { get; set; }

    [DataMember]
    public virtual string Email { get; set; }
}
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
Bastien Vandamme
  • 17,659
  • 30
  • 118
  • 200
  • Will it compile? Yes. Do we know if it's correct for your needs? Of course not. As it stands right now, this is not a good question. – David L Jul 04 '14 at 04:31
  • If you're referring to a POCO in the context of Entity Framework Code-First, then no, Entity Framework will not support your class. You need a parameterless constructor. – Federico Berasategui Jul 04 '14 at 04:32
  • 1
    Nor will WCF, which based in the `[DataContract]` attribute you're targeting. – Federico Berasategui Jul 04 '14 at 04:33
  • POCO is not strictly defined term (i.e variant of SO definition is in linked [duplicate question](http://stackoverflow.com/questions/250001/poco-definition) ). So "can POCO have XXXX" can't be answered better than the linked question does already. If you use particular framework POCO may mean some specific subset of "plain object" and may or may not require particular features as presence or absence of default constructor. Feel free to ask more specific version separately if needed. – Alexei Levenkov Jul 04 '14 at 04:44
  • 1
    Side note: I personally would not call such object "POCO" as your code implies inheritance and feels outside of scope of "plain" objects. – Alexei Levenkov Jul 04 '14 at 04:46
  • I don't see the answer of this specific question in the duplicate question but ok... Asking for a definition is not the same as asking for a specific question. I saw many other questions about POCO that are also duplicates in this case. pfffff – Bastien Vandamme Jul 04 '14 at 04:48

1 Answers1

2

A POCO object can contain other constructors but a default constructor is needed for deserialization as that process tries to create a default instance of the object and then sets the properties.

After some research it seems that the datacontract serializer does not use or even call the default constructor. Using this you could exclude a default ctor and still serialize your POCO. Whether or not you should is an implementation detail that you and your team would have to decide.

DataContractSerializer Tests:

[Test]
public void SerializerTest()
{
    var s = new SerializeMe(2);
    s.Name = "Test";
    DataContractSerializer dcs = new DataContractSerializer(typeof(SerializeMe));
    Stream ms = new MemoryStream();
    var writer = XmlWriter.Create(ms);
    Assert.DoesNotThrow(() => dcs.WriteObject(writer, s));
    writer.Close();

    ms.Position = 0;
    var reader = new StreamReader(ms);
    var xml = reader.ReadToEnd();
    Console.WriteLine(xml);
}

[Test]
public void DeserializeTest()
{
    var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><SerializeMe xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.datacontract.org/2004/07/Test\"><Id>2</Id><Name>Test</Name></SerializeMe>";
    DataContractSerializer dcs = new DataContractSerializer(typeof(SerializeMe));            
    XmlReader reader = XmlReader.Create(new StringReader(xml));
    var obj = dcs.ReadObject(reader) as SerializeMe;
    Assert.AreEqual(obj.Name, "Test");
}

[DataContract]
public class SerializeMe
{
    public SerializeMe(int id)
    {
        this.Id = id;
    }
    [DataMember]
    public int Id { get; private set; }
    [DataMember]
    public string Name { get; set; }
}
Gary.S
  • 7,076
  • 1
  • 26
  • 36
  • Correct me but I can still write my own deserialization process. – Bastien Vandamme Jul 04 '14 at 04:37
  • @B413 yes you can do that, but why would you? there are a bunch of serialization mechanisms built into .Net, there's no need to reinvent the wheel. – Federico Berasategui Jul 04 '14 at 04:37
  • 1
    I like this one "there's no need to reinvent the wheel". Believe me there is always a reason to reinvent the wheel. The best example is probably the .NET framework. I think this sentence should be banished from IT... and most other engineering jobs. – Bastien Vandamme Jul 04 '14 at 04:43