Я попытаюсь создать библиотеку C# для сериализации объектов в GeoJSON, используя Json.NET (для сериализации) и GeoAPI.NET (для определений геометрии).
Я думал о двух разных подходах к реализации сериализации, и мне не ясно, какой из них будет лучшим. Они есть:
Подход 1 — Пользовательские атрибуты
Первый подход предполагает создание нескольких настраиваемых атрибутов, которые можно применить к любому классу для изменения сериализации. Например, класс может быть оформлен так:
[GeoJsonFeature]
public class Building
{
[GeoJsonId]
public Guid Id { get; set; }
[GeoJsonProperty]
public string Name { get; set; }
[GeoJsonProperty]
public int Floorcount { get; set; }
[GeoJsonGeometry]
public GeoAPI.Geometries.IGeometry Geometry { get; set; }
}
Тогда сериализация объекта будет такой же простой, как:
JsonNetResult jsonNetResult = new JsonNetResult();
jsonNetResult.Formatting = Formatting.Indented;
jsonNetResult.Data = building;
return jsonNetResult;
Преимущество этого подхода заключается в том, что любой бизнес-объект можно превратить в объект GeoJSON при условии, что он обладает необходимыми свойствами (например, Geometry). Недостатком было бы то, что мне нужно было бы создать ряд настраиваемых атрибутов для поддержки сериализации. Кроме того, это приводит к «замутнению» бизнес-объекта.
Наконец, я еще не определил, возможен ли такой подход с JSON.NET, хотя кажется, что будет.
Подход 2 — Пользовательский конвертер JsonConverter
Второй подход предполагает создание пользовательских конвертеров для различных типов. Например, у меня может быть GeoJsonConverter, который при передаче объекта заданного типа, скажем, Feature, создает объект GeoJSON. Это может выглядеть так:
public class GeoJsonFeatureConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer)
{
// serializing code here
}
public override void ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
{
// deserializing code here
}
public override bool CanConvert(Type objectType)
{
return typeof(Feature).IsAssignableFrom(objectType);
}
}
Затем я смогу сериализовать в GeoJson так:
JsonNetResult jsonNetResult = new JsonNetResult();
jsonNetResult.Formatting = Formatting.Indented;
jsonNetResult.SerializerSettings.Converters.Add(new GeoJsonFeatureConverter());
jsonNetResult.Data = building;
Преимущество здесь в том, что это кажется легче создать. Я доказал, что этот подход возможен с помощью очень простого прототипа. Кроме того, класс Feature
уже определен, если я ссылаюсь на NetTopologySuite.
Недостатком будет то, что мои бизнес-объекты должны быть сопоставлены с Feature
перед сериализацией. Хотя это можно считать преимуществом, поскольку это может обеспечить естественную развязку между слоями. В обоих случаях определенно будет тесная связь с GeoAPI, а в последнем — с NetTopologySuite. Я думаю, что я в порядке с этим.
Я знаю о нескольких других доступных сериализаторах GeoJson, таких как GeoJson.NET, однако мне нужен подход, совместимый с Json.NET API, так как это наш предпочтительный сериализатор.
Видите ли вы какие-либо очевидные причины, по которым один подход предпочтительнее другого? Возможно, есть другой подход, о котором я не знаю?
К вашему сведению, я склоняюсь ко второму подходу. Кажется, что это было бы проще реализовать и в целом было бы чище. Мне также нравится естественная граница между объектами домена и объектами GeoJson, которые он создает.