Skip to content

Commit 949953e

Browse files
committed
allow property injection for formatters
1 parent c573d26 commit 949953e

5 files changed

Lines changed: 254 additions & 37 deletions

JSONAPI/Json/LinkFormatter.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ namespace JSONAPI.Json
1010
/// </summary>
1111
public class LinkFormatter : ILinkFormatter
1212
{
13-
private readonly IMetadataFormatter _metadataFormatter;
13+
private IMetadataFormatter _metadataFormatter;
1414
private const string HrefKeyName = "href";
1515
private const string MetaKeyName = "meta";
1616

17+
/// <summary>
18+
/// Constructs a LinkFormatter
19+
/// </summary>
20+
public LinkFormatter()
21+
{
22+
23+
}
24+
1725
/// <summary>
1826
/// Constructs a LinkFormatter
1927
/// </summary>
@@ -23,6 +31,23 @@ public LinkFormatter(IMetadataFormatter metadataFormatter)
2331
_metadataFormatter = metadataFormatter;
2432
}
2533

34+
/// <summary>
35+
/// The formatter to use for metadata on the link object
36+
/// </summary>
37+
/// <exception cref="InvalidOperationException"></exception>
38+
public IMetadataFormatter MetadataFormatter
39+
{
40+
get
41+
{
42+
return _metadataFormatter ?? (_metadataFormatter = new MetadataFormatter());
43+
}
44+
set
45+
{
46+
if (_metadataFormatter != null) throw new InvalidOperationException("This property can only be set once.");
47+
_metadataFormatter = value;
48+
}
49+
}
50+
2651
public Task Serialize(ILink link, JsonWriter writer)
2752
{
2853
if (link.Metadata == null)
@@ -35,7 +60,7 @@ public Task Serialize(ILink link, JsonWriter writer)
3560
writer.WritePropertyName(HrefKeyName);
3661
writer.WriteValue(link.Href);
3762
writer.WritePropertyName(MetaKeyName);
38-
_metadataFormatter.Serialize(link.Metadata, writer);
63+
MetadataFormatter.Serialize(link.Metadata, writer);
3964
writer.WriteEndObject();
4065
}
4166
return Task.FromResult(0);

JSONAPI/Json/RelationshipObjectFormatter.cs

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,17 @@ public class RelationshipObjectFormatter : IRelationshipObjectFormatter
1616
private const string LinkageKeyName = "data";
1717
private const string MetaKeyName = "meta";
1818

19-
private readonly ILinkFormatter _linkFormatter;
20-
private readonly IResourceLinkageFormatter _resourceLinkageFormatter;
21-
private readonly IMetadataFormatter _metadataFormatter;
19+
private ILinkFormatter _linkFormatter;
20+
private IResourceLinkageFormatter _resourceLinkageFormatter;
21+
private IMetadataFormatter _metadataFormatter;
22+
23+
/// <summary>
24+
/// Creates a new RelationshipObjectFormatter
25+
/// </summary>
26+
public RelationshipObjectFormatter ()
27+
{
28+
29+
}
2230

2331
/// <summary>
2432
/// Creates a new RelationshipObjectFormatter
@@ -30,6 +38,45 @@ public RelationshipObjectFormatter(ILinkFormatter linkFormatter, IResourceLinkag
3038
_metadataFormatter = metadataFormatter;
3139
}
3240

41+
private ILinkFormatter LinkFormatter
42+
{
43+
get
44+
{
45+
return _linkFormatter ?? (_linkFormatter = new LinkFormatter());
46+
}
47+
set
48+
{
49+
if (_linkFormatter != null) throw new InvalidOperationException("This property can only be set once.");
50+
_linkFormatter = value;
51+
}
52+
}
53+
54+
private IResourceLinkageFormatter ResourceLinkageFormatter
55+
{
56+
get
57+
{
58+
return _resourceLinkageFormatter ?? (_resourceLinkageFormatter = new ResourceLinkageFormatter());
59+
}
60+
set
61+
{
62+
if (_resourceLinkageFormatter != null) throw new InvalidOperationException("This property can only be set once.");
63+
_resourceLinkageFormatter = value;
64+
}
65+
}
66+
67+
private IMetadataFormatter MetadataFormatter
68+
{
69+
get
70+
{
71+
return _metadataFormatter ?? (_metadataFormatter = new MetadataFormatter());
72+
}
73+
set
74+
{
75+
if (_metadataFormatter != null) throw new InvalidOperationException("This property can only be set once.");
76+
_metadataFormatter = value;
77+
}
78+
}
79+
3380
public Task Serialize(IRelationshipObject relationshipObject, JsonWriter writer)
3481
{
3582
if (relationshipObject.Metadata == null && relationshipObject.SelfLink == null &&
@@ -60,12 +107,12 @@ protected virtual void SerializeLinks(IRelationshipObject relationshipObject, Js
60107
if (relationshipObject.SelfLink != null)
61108
{
62109
writer.WritePropertyName(SelfLinkKeyName);
63-
_linkFormatter.Serialize(relationshipObject.SelfLink, writer);
110+
LinkFormatter.Serialize(relationshipObject.SelfLink, writer);
64111
}
65112
if (relationshipObject.RelatedResourceLink != null)
66113
{
67114
writer.WritePropertyName(RelatedLinkKeyName);
68-
_linkFormatter.Serialize(relationshipObject.RelatedResourceLink, writer);
115+
LinkFormatter.Serialize(relationshipObject.RelatedResourceLink, writer);
69116
}
70117

71118
writer.WriteEndObject();
@@ -80,7 +127,7 @@ protected virtual void SerializeLinkage(IRelationshipObject relationshipObject,
80127
if (relationshipObject.Linkage != null)
81128
{
82129
writer.WritePropertyName(LinkageKeyName);
83-
_resourceLinkageFormatter.Serialize(relationshipObject.Linkage, writer);
130+
ResourceLinkageFormatter.Serialize(relationshipObject.Linkage, writer);
84131
}
85132
}
86133

@@ -92,7 +139,7 @@ protected virtual void SerializeMetadata(IRelationshipObject relationshipObject,
92139
if (relationshipObject.Metadata != null)
93140
{
94141
writer.WritePropertyName(MetaKeyName);
95-
_metadataFormatter.Serialize(relationshipObject.Metadata, writer);
142+
MetadataFormatter.Serialize(relationshipObject.Metadata, writer);
96143
}
97144
}
98145

@@ -114,10 +161,10 @@ public async Task<IRelationshipObject> Deserialize(JsonReader reader, string cur
114161
switch (propertyName)
115162
{
116163
case LinkageKeyName:
117-
linkage = await _resourceLinkageFormatter.Deserialize(reader, currentPath + "/" + LinkageKeyName);
164+
linkage = await ResourceLinkageFormatter.Deserialize(reader, currentPath + "/" + LinkageKeyName);
118165
break;
119166
case MetaKeyName:
120-
metadata = await _metadataFormatter.Deserialize(reader, currentPath + "/" + MetaKeyName);
167+
metadata = await MetadataFormatter.Deserialize(reader, currentPath + "/" + MetaKeyName);
121168
break;
122169
}
123170
}

JSONAPI/Json/ResourceCollectionDocumentFormatter.cs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Linq;
34
using System.Threading.Tasks;
@@ -11,14 +12,22 @@ namespace JSONAPI.Json
1112
/// </summary>
1213
public class ResourceCollectionDocumentFormatter : IResourceCollectionDocumentFormatter
1314
{
14-
private readonly IResourceObjectFormatter _resourceObjectFormatter;
15-
private readonly IMetadataFormatter _metadataFormatter;
15+
private IResourceObjectFormatter _resourceObjectFormatter;
16+
private IMetadataFormatter _metadataFormatter;
1617
private const string PrimaryDataKeyName = "data";
1718
private const string RelatedDataKeyName = "included";
1819
private const string MetaKeyName = "meta";
19-
20+
21+
/// <summary>
22+
/// Creates a ResourceCollectionDocumentFormatter
23+
/// </summary>
24+
public ResourceCollectionDocumentFormatter()
25+
{
26+
27+
}
28+
2029
/// <summary>
21-
/// Creates a SingleResourceDocumentFormatter
30+
/// Creates a ResourceCollectionDocumentFormatter
2231
/// </summary>
2332
/// <param name="resourceObjectFormatter"></param>
2433
/// <param name="metadataFormatter"></param>
@@ -28,6 +37,40 @@ public ResourceCollectionDocumentFormatter(IResourceObjectFormatter resourceObje
2837
_metadataFormatter = metadataFormatter;
2938
}
3039

40+
/// <summary>
41+
/// The formatter to use for resource objects found in this document
42+
/// </summary>
43+
/// <exception cref="InvalidOperationException"></exception>
44+
public IResourceObjectFormatter ResourceObjectFormatter
45+
{
46+
get
47+
{
48+
return _resourceObjectFormatter ?? (_resourceObjectFormatter = new ResourceObjectFormatter());
49+
}
50+
set
51+
{
52+
if (_resourceObjectFormatter != null) throw new InvalidOperationException("This property can only be set once.");
53+
_resourceObjectFormatter = value;
54+
}
55+
}
56+
57+
/// <summary>
58+
/// The formatter to use for document-level metadata
59+
/// </summary>
60+
/// <exception cref="InvalidOperationException"></exception>
61+
public IMetadataFormatter MetadataFormatter
62+
{
63+
get
64+
{
65+
return _metadataFormatter ?? (_metadataFormatter = new MetadataFormatter());
66+
}
67+
set
68+
{
69+
if (_metadataFormatter != null) throw new InvalidOperationException("This property can only be set once.");
70+
_metadataFormatter = value;
71+
}
72+
}
73+
3174
public Task Serialize(IResourceCollectionDocument document, JsonWriter writer)
3275
{
3376
writer.WriteStartObject();
@@ -37,7 +80,7 @@ public Task Serialize(IResourceCollectionDocument document, JsonWriter writer)
3780
writer.WriteStartArray();
3881
foreach (var resourceObject in document.PrimaryData)
3982
{
40-
_resourceObjectFormatter.Serialize(resourceObject, writer);
83+
ResourceObjectFormatter.Serialize(resourceObject, writer);
4184
}
4285
writer.WriteEndArray();
4386

@@ -47,15 +90,15 @@ public Task Serialize(IResourceCollectionDocument document, JsonWriter writer)
4790
writer.WriteStartArray();
4891
foreach (var resourceObject in document.RelatedData)
4992
{
50-
_resourceObjectFormatter.Serialize(resourceObject, writer);
93+
ResourceObjectFormatter.Serialize(resourceObject, writer);
5194
}
5295
writer.WriteEndArray();
5396
}
5497

5598
if (document.Metadata != null)
5699
{
57100
writer.WritePropertyName(MetaKeyName);
58-
_metadataFormatter.Serialize(document.Metadata, writer);
101+
MetadataFormatter.Serialize(document.Metadata, writer);
59102
}
60103

61104
writer.WriteEndObject();
@@ -91,7 +134,7 @@ public async Task<IResourceCollectionDocument> Deserialize(JsonReader reader, st
91134
primaryData = await DeserializePrimaryData(reader, currentPath + "/" + PrimaryDataKeyName);
92135
break;
93136
case MetaKeyName:
94-
metadata = await _metadataFormatter.Deserialize(reader, currentPath + "/" + MetaKeyName);
137+
metadata = await MetadataFormatter.Deserialize(reader, currentPath + "/" + MetaKeyName);
95138
break;
96139
default:
97140
reader.Skip();
@@ -115,7 +158,7 @@ private async Task<IResourceObject[]> DeserializePrimaryData(JsonReader reader,
115158
if (reader.TokenType == JsonToken.EndArray)
116159
break;
117160

118-
var resourceObject = await _resourceObjectFormatter.Deserialize(reader, currentPath + "/" + index);
161+
var resourceObject = await ResourceObjectFormatter.Deserialize(reader, currentPath + "/" + index);
119162
primaryData.Add(resourceObject);
120163

121164
index++;

0 commit comments

Comments
 (0)