Two sets of serialization attributes on same class
I'm facing a class design problem.
I'm using data contract serializer.
So, in the assembly that is shared across all my applications, I have something like this:
// Assembly DataContracts.dll: .NET 3.0, used by every subsystems
[DataContract]
public class User
{
/// <summary>Nickname.</summary>
[DataMember]
public string displayName;
}
There are many more fields: I've left only the displayName trying to compact my code listings.
开发者_如何学运维However, one of the applications is a server, who needs another serializer to be applied to the same class, in the following way:
// Assembly ServerDatabase.dll, .NET 4.0, used only by server.
[EseTable]
public class User
{
/// <summary>Nickname.</summary>
[EseText(bUnicode=true, maxChars=71)]
public string displayName;
}
ServerDatabase.dll is linked to .NET 4. Moreover, [Ese*] attributes are defined in a DLL that can only be loaded by the server component due to the security reasons out of my control, so I can't just have a single class with both sets of attributes shared by every subsystem.
Currently, I wrote something like this:
// DataContracts.dll
[DataContract]
public class User
{
[DataMember]
public string displayName;
}
// ServerDatabase.dll
[EseTable]
public class UserRecord: User
{
[EseText(bUnicode=true, maxChars=71)]
new public string displayName { get { return base.displayName; } set { base.displayName=value; } }
// Note I need to implement an upcasting copy constructor, to convert from User to UserRecord :-(
public UserRecord(User that)
{
base.displayName=that.displayName;
}
}
I don't really like my solution: looks like a hack, and error-prone. Any different better ideas, corrections or fixes?
Thanks in advance!
I don't think that solution will work well, as neither sub-types nor base-types need be handled by the "other" serializer (if you see what I mean).
Personally, I would create a DTO layer for the "unusual" tier, and map between them. So pretty much like the example in the question, perhaps using AutoMapper. The other option is to see if the other serializer supports metadata from sources other than attributes. Some do, some don't.
If automapper causes problems you could simply annotate your server DTO with the same DCS attributes, and use DCS to translate the model, i.e.
[EseTable, DataContract]
public class User
{
/// <summary>Nickname.</summary>
[EseText(bUnicode=true, maxChars=71), DataMember]
public string displayName;
}
As long as the names match, DCS should be happy enough with this. i.e. use DCS to serialize from one model and deserialize as the other model. I use similar tricks in a few places (although I tend to use my own serializer for this, not DCS - faster ;p)
精彩评论