Skip to content

Commit

Permalink
Handle XmlIgnoreAttribute #3.
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanLarsson committed Sep 9, 2018
1 parent 7e98b71 commit c937897
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
18 changes: 18 additions & 0 deletions Gu.Xml.Tests/XmlTests.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ public void XmlElementAttribute()
Assert.AreEqual(expected, actual);
}

[Test]
public void XmlIgnoreAttribute()
{
var with = new WithXmlIgnore { Value = 1 };
var expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + Environment.NewLine +
"<WithXmlIgnore>" + Environment.NewLine +
"</WithXmlIgnore>";

var actual = Xml.Serialize(with);
Assert.AreEqual(expected, actual);
}

public class WithGetSet
{
public int Value { get; set; }
Expand Down Expand Up @@ -115,6 +127,12 @@ public class WithXmlElement
[XmlElement("Name")]
public int Value { get; set; }
}

public class WithXmlIgnore
{
[XmlIgnore]
public int Value { get; set; }
}
}
}
}
14 changes: 4 additions & 10 deletions Gu.Xml/Writers/ComplexValueWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Xml;
using System.Xml.Serialization;

public class ComplexValueWriter
Expand Down Expand Up @@ -36,17 +38,9 @@ IEnumerable<ElementWriter> Elements()
{
foreach (var property in type.GetProperties())
{
if (property.SetMethod != null ||
Attribute.GetCustomAttribute(property.GetMethod, typeof(CompilerGeneratedAttribute)) != null)
if (ElementWriter.TryCreate(property, out var writer))
{
if (Attribute.GetCustomAttribute(property, typeof(XmlElementAttribute)) is XmlElementAttribute xmlElement)
{
yield return ElementWriter.Create(xmlElement.ElementName, property);
}
else
{
yield return ElementWriter.Create(property.Name, property);
}
yield return writer;
}
}
}
Expand Down
47 changes: 39 additions & 8 deletions Gu.Xml/Writers/ElementWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
{
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Xml.Serialization;

public abstract class ElementWriter
{
Expand All @@ -12,19 +14,48 @@ protected ElementWriter(string name)

public string Name { get; }

public static ElementWriter Create(string name, PropertyInfo property)
{
return (ElementWriter)typeof(ElementWriter)
.GetMethod(nameof(CreateWriter), BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(property.ReflectedType, property.PropertyType)
.Invoke(null, new object[] { name, property });
}

public abstract void Write<T>(XmlWriter writer, T source);

private static ElementWriter<TSource, TValue> CreateWriter<TSource, TValue>(string name, PropertyInfo property)
{
return new ElementWriter<TSource, TValue>(name, (Func<TSource, TValue>)Delegate.CreateDelegate(typeof(Func<TSource, TValue>), property.GetMethod));
}

public static bool TryCreate(PropertyInfo property, out ElementWriter writer)
{
if (property.GetMethod != null &&
!IsIgnoredCalculated() &&
Attribute.GetCustomAttribute(property, typeof(XmlIgnoreAttribute)) == null &&
Attribute.GetCustomAttribute(property, typeof(XmlAttributeAttribute)) == null)
{
writer = (ElementWriter) typeof(ElementWriter)
.GetMethod(nameof(CreateWriter),
BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(property.ReflectedType, property.PropertyType)
.Invoke(null, new object[] {Name(), property});
return true;
}

writer = null;
return false;

bool IsIgnoredCalculated()
{
return property.SetMethod == null &&
Attribute.GetCustomAttribute(property.GetMethod, typeof(CompilerGeneratedAttribute)) == null &&
Attribute.GetCustomAttribute(property.GetMethod, typeof(XmlElementAttribute)) == null;
}

string Name()
{
if (Attribute.GetCustomAttribute(property, typeof(XmlElementAttribute)) is XmlElementAttribute xmlElement &&
xmlElement.ElementName is string name)
{
return name;
}

return property.Name;
}
}
}
}

0 comments on commit c937897

Please sign in to comment.