rikimaru0345 / Ceras

Universal binary serializer for a wide variety of scenarios https://discord.gg/FGaCX4c
MIT License
483 stars 53 forks source link

DataContractSerializer compatibility? #37

Closed fredliex closed 5 years ago

fredliex commented 5 years ago

hi, any plan make DataContractSerializer compatibility? like that AArnott/MessagePack-CSharp#22

rikimaru0345 commented 5 years ago

Hey :) Can you elaborate what compatibility means here?

Is this just about respecting the attributes? Like including the same members as the data contract serializer would?

In tgat case it should he easy. But what kind of api would you want for that? Would you put the setting in TypeConfig (so really per type)? Or should it rather be a method? Like typeConfig.ConfigureLikeDataContractSerializer()?

fredliex commented 5 years ago

I have a lot of existing WCF project and DataContract Model. plan transform from WCF to WebAPI or RPC, hope reuse existing DataContract model project, MessagePack-CSharp can detect DataContractAttribute, DataMemberAttribute...etc, but without resolver can simulate DataContractSerializer behavior on nonpublic member,

ex:

[DataContract]
public class Master {
    [DataMember]
    public string A { get; set; }
    [DataMember]
    internal Detail B { get; set; }
}
public class Detail {
    public string B1 { get; set; }
    internal string B2 { get; set; }
}

in DataContractSerializer, include A and B1. in MessagePack-CSharp.ContractlessStandardResolver, only A, lack B2. in MessagePack-CSharp.ContractlessStandardResolverAllowPrivate, include A,B1,B2. but B2 is unnecessary.

PS: those projects no need to communicate with other languages, focus only on .NET.

rikimaru0345 commented 5 years ago

Ok so this is indeed just about what gets included or not included, right?

I can certainly make a mode or setting or something that will set all the includes/ignores for all members the same way DataContractSerializer would do it.

I think I can add this quickly tomorrow. But I'd like to ask one more time if I really understood you right. Like is that really what you want? (would be bad if I were missing something here)

fredliex commented 5 years ago

maybe... when with DataContractAttribute then include all DataMemberAttribute members whether public or nonpublic, like DataContractSerializer. when without DataContractAttribute then follow the DefaultTargets behavior.

What do you think?

rikimaru0345 commented 5 years ago

Yeah that's totally doable. I think I'll add that.

I think it will be best to make it flexible, so you will be able to enable this kind of behavior on a per-type basis.

I imagine it like this:

config.OnConfigNewType = t => 
{
   t.ConfigureLikeDataContractSerializer();
};

that will traverse the type and its members and setup everything just like you described. That way you could simply call the method always (like I just did in the example above). Or do it on a per type-basis as well.

Does that sound good?

fredliex commented 5 years ago

so, I can do that, right?

config.OnConfigNewType = t => {
    if (t.Type.GetCustomAttribute<DataContractAttribute>() != null) {
        t.ConfigureLikeDataContractSerializer();
    } else {
        .......
    }
};

I think it can. :smile:

rikimaru0345 commented 5 years ago

Yeah, you could do that.

I'll implement it like you said here:

when with DataContractAttribute ... -> then like DataContractSerializer.

when without DataContractAttribute then follow the DefaultTargets behavior.

so you wouldn't need to have to do the check; the ConfigureLikeDataContractSerializer function would check for the attribute already anyway.

fredliex commented 5 years ago

maybe the word ConfigureLikeDataContractSerializer has a bit confused. if a type without DataContractAttribute call ConfigureLikeDataContractSerializer, what is meaning? change to bool TrySimulateDataContractSerializer() or other word, will it be more clear?

fredliex commented 5 years ago

If so?

config.OnConfigNewType = t => {
   //ConfigureLikeDataContractSerializer return false when without DataContractAttribute
   if (!t.ConfigureLikeDataContractSerializer()) {
   } else if (t == someType) {
      .... special for someType....
   } else {
      //.... nothing to do, follow the MemberConfigAttribute on class....
   }
};

is better?

rikimaru0345 commented 5 years ago

@fredliex I pushed a change that implements the feature. Can you check it out and tell me if that is how you imagined it?

There is no nuget build for it yet.

fredliex commented 5 years ago

I think it is good. The meaning is clear. 😃

rikimaru0345 commented 5 years ago

@fredliex I just pushed a nuget package of the newest build. It contains those changes as well now (in case you didn't have time to compile them yourself). I'll consider this implemented now. If there's something wrong or so, feel free to reopen this :)