private SetterMethod Read(IDataReader reader, ObjectMember field, object value, Dictionary <string, object> values)
        {
            string name = field.Name;

            if (!reader.IsEmptyElement)
            {
                var serializerAttribute = field.Member.GetCustomAttribute <CustomFormatterAttribute>(false);
                var serializer          = serializerAttribute?.Formatter ?? FormatterFromReader(reader, out var type);
                int cycleId             = reader.ReadId();

                reader.ReadStartNode(name);
                object cycleValue = values[name] = serializer.Read(reader, value);
                if (CycleUtility.ValidCycleType(serializer.Type))
                {
                    CycleUtility.GetInstance(reader).AddReference(cycleId, cycleValue);
                }
                reader.ReadEndNode(name);
                // no setter method required
                return(null);
            }
            else
            {
                SetterMethod referenceReader = ReadReferencedObject(reader, field.Set);
                values[name] = null;
                reader.ReadEmptyNode(field.Name);
                return(referenceReader);
            }
        }
 public void Write(IDataWriter writer, object o)
 {
     if (CycleUtility.ValidCycleType(o.GetType()))
     {
         var cycleUtil = CycleUtility.GetInstance(writer);
         if (cycleUtil.TryGetReferenceId(o, out int id))
         {
             writer.WriteReference(id);
             return;
         }
         else
         {
             writer.WriteId(id);
         }
     }
     foreach (var field in members)
     {
         if (field.HasGetter())
         {
             var fieldValue = field.Get(o);
             Write(writer, field, fieldValue);
         }
     }
 }