Skip to content

Commit 883bfee

Browse files
committed
chore: wiring up new resource object builders to dependency graph
1 parent e5bbda2 commit 883bfee

15 files changed

+85
-75
lines changed

src/JsonApiDotNetCore/Extensions/IServiceCollectionExtensions.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,19 +240,24 @@ private static void AddServerSerialization(IServiceCollection services)
240240
services.AddScoped<IJsonApiDeserializer, RequestDeserializer>();
241241
services.AddScoped<IResourceObjectBuilderSettingsProvider, ResourceObjectBuilderSettingsProvider>();
242242
services.AddScoped<IJsonApiSerializerFactory, ResponseSerializerFactory>();
243-
services.AddScoped<IResourceObjectBuilder, ResponseResourceObjectBuilder>();
244-
services.AddScoped<ResponseResourceObjectBuilder>();
245243
services.AddScoped<ILinkBuilder, LinkBuilder>();
246244
services.AddScoped(typeof(IMetaBuilder<>), typeof(MetaBuilder<>));
247245
services.AddScoped(typeof(ResponseSerializer<>));
248246
services.AddScoped(sp => sp.GetRequiredService<IJsonApiSerializerFactory>().GetSerializer());
247+
248+
services.AddScoped<IResourceObjectBuilder, ResponseResourceObjectBuilder>();
249249
}
250250

251251
private static void AddClientSerialization(IServiceCollection services)
252252
{
253-
services.AddScoped<IRequestSerializer, RequestSerializer>();
254253
services.AddScoped<IResponseDeserializer, ResponseDeserializer>();
255-
services.AddScoped<RequestResourceObjectBuilder>();
254+
255+
services.AddScoped<IRequestSerializer>(sp =>
256+
{
257+
var resourceObjectBuilder = new ResourceObjectBuilder(sp.GetService<IResourceGraph>(), sp.GetService<IContextEntityProvider>(), sp.GetService<IResourceObjectBuilderSettingsProvider>().Get());
258+
return new RequestSerializer(sp.GetService<IFieldsExplorer>(), sp.GetService<IResourceGraph>(), resourceObjectBuilder);
259+
});
260+
256261
}
257262

258263
private static void AddOperationServices(IServiceCollection services)

src/JsonApiDotNetCore/JsonApiDotNetCore.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,10 @@
5656
<Folder Include="Query\Contracts\" />
5757
<Folder Include="Query\Common\" />
5858
</ItemGroup>
59+
<ItemGroup>
60+
<Compile Remove="Serialization\Client\RequestResourceObjectBuilder.cs" />
61+
</ItemGroup>
62+
<ItemGroup>
63+
<None Include="Serialization\Client\RequestResourceObjectBuilder.cs" Condition=" '$(EnableDefaultCompileItems)' == 'true' " />
64+
</ItemGroup>
5965
</Project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace JsonApiDotNetCore.Serialization.Client
2+
{
3+
public interface IRequestResourceObjectBuilder : IResourceObjectBuilder
4+
{
5+
6+
}
7+
}
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
using JsonApiDotNetCore.Internal.Contracts;
2-
using JsonApiDotNetCore.Models;
1+
//using JsonApiDotNetCore.Internal.Contracts;
2+
//using JsonApiDotNetCore.Models;
33

4-
namespace JsonApiDotNetCore.Serialization
5-
{
6-
public class RequestResourceObjectBuilder : BaseResourceObjectBuilder, IResourceObjectBuilder
7-
{
8-
public RequestResourceObjectBuilder(IResourceGraph resourceGraph, IContextEntityProvider provider) : base(resourceGraph, provider, new ResourceObjectBuilderSettings()) { }
4+
//namespace JsonApiDotNetCore.Serialization
5+
//{
6+
// public class RequestResourceObjectBuilder : ResourceObjectBuilder, IResourceObjectBuilder
7+
// {
8+
// public RequestResourceObjectBuilder(IResourceGraph resourceGraph, IContextEntityProvider provider) : base(resourceGraph, provider, new ResourceObjectBuilderSettings()) { }
99

10-
protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable entity)
11-
{
12-
return new RelationshipEntry { Data = GetRelatedResourceLinkage(relationship, entity) };
13-
}
14-
}
15-
}
10+
// protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable entity)
11+
// {
12+
// return new RelationshipEntry { Data = GetRelatedResourceLinkage(relationship, entity) };
13+
// }
14+
// }
15+
//}

src/JsonApiDotNetCore/Serialization/Client/RequestSerializer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace JsonApiDotNetCore.Serialization.Client
1111
{
12+
1213
/// <summary>
1314
/// Client serializer implementation of <see cref="BaseDocumentBuilder"/>
1415
/// Note that this implementation does not override the default implementation
@@ -22,7 +23,7 @@ public class RequestSerializer : BaseDocumentBuilder, IRequestSerializer
2223
private readonly IFieldsExplorer _fieldExplorer;
2324
public RequestSerializer(IFieldsExplorer fieldExplorer,
2425
IContextEntityProvider provider,
25-
RequestResourceObjectBuilder resourceObjectBuilder)
26+
IResourceObjectBuilder resourceObjectBuilder)
2627
: base(resourceObjectBuilder, provider)
2728
{
2829
_fieldExplorer = fieldExplorer;

src/JsonApiDotNetCore/Serialization/Common/IBaseResourceObjectBuilder.cs renamed to src/JsonApiDotNetCore/Serialization/Common/IResourceObjectBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace JsonApiDotNetCore.Serialization
66
/// <summary>
77
/// Abstract base class for serialization. Converts entities in to <see cref="ResourceObject"/>s
88
/// given a list of attributes and relationships.
9-
/// </summary>
9+
/// </summary>
1010
public interface IResourceObjectBuilder
1111
{
1212
/// <summary>

src/JsonApiDotNetCore/Serialization/Common/ResourceObjectBuilder.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ namespace JsonApiDotNetCore.Serialization
1313
/// Abstract base class for serialization. Converts entities in to <see cref="ResourceObject"/>s
1414
/// given a list of attributes and relationships.
1515
/// </summary>
16-
public abstract class BaseResourceObjectBuilder
16+
public class ResourceObjectBuilder : IResourceObjectBuilder
1717
{
1818
protected readonly IResourceGraph _resourceGraph;
1919
protected readonly IContextEntityProvider _provider;
2020
private readonly ResourceObjectBuilderSettings _settings;
2121
private const string _identifiablePropertyName = nameof(Identifiable.Id);
2222

23-
protected BaseResourceObjectBuilder(IResourceGraph resourceGraph, IContextEntityProvider provider, ResourceObjectBuilderSettings settings)
23+
public ResourceObjectBuilder(IResourceGraph resourceGraph, IContextEntityProvider provider, ResourceObjectBuilderSettings settings)
2424
{
2525
_resourceGraph = resourceGraph;
2626
_provider = provider;
@@ -35,31 +35,39 @@ protected BaseResourceObjectBuilder(IResourceGraph resourceGraph, IContextEntity
3535
/// <param name="attributes">Attributes to include in the building process</param>
3636
/// <param name="relationships">Relationships to include in the building process</param>
3737
/// <returns>The resource object that was built</returns>
38-
public ResourceObject Build(IIdentifiable entity, IEnumerable<AttrAttribute> attributes, IEnumerable<RelationshipAttribute> relationships)
38+
public ResourceObject Build(IIdentifiable entity, IEnumerable<AttrAttribute> attributes = null, IEnumerable<RelationshipAttribute> relationships = null)
3939
{
4040
var resourceContext = _provider.GetContextEntity(entity.GetType());
4141

4242
// populating the top-level "type" and "id" members.
4343
var ro = new ResourceObject { Type = resourceContext.EntityName, Id = entity.StringId.NullIfEmpty() };
4444

4545
// populating the top-level "attribute" member of a resource object. never include "id" as an attribute
46-
attributes = attributes.Where(attr => attr.InternalAttributeName != _identifiablePropertyName);
47-
if (attributes.Any())
48-
{
49-
ro.Attributes = new Dictionary<string, object>();
50-
foreach (var attr in attributes)
51-
AddAttribute(entity, ro, attr);
52-
}
46+
if (attributes != null && (attributes = attributes.Where(attr => attr.InternalAttributeName != _identifiablePropertyName)).Any())
47+
ProcessAttributes(entity, attributes, ro);
5348

5449
// populating the top-level "relationship" member of a resource object.
50+
if (relationships != null)
51+
ProcessRelationships(entity, relationships, ro);
52+
53+
return ro;
54+
}
55+
56+
private void ProcessRelationships(IIdentifiable entity, IEnumerable<RelationshipAttribute> relationships, ResourceObject ro)
57+
{
5558
foreach (var rel in relationships)
5659
{
5760
var relData = GetRelationshipData(rel, entity);
5861
if (relData != null)
5962
(ro.Relationships = ro.Relationships ?? new Dictionary<string, RelationshipEntry>()).Add(rel.PublicRelationshipName, relData);
6063
}
64+
}
6165

62-
return ro;
66+
private void ProcessAttributes(IIdentifiable entity, IEnumerable<AttrAttribute> attributes, ResourceObject ro)
67+
{
68+
ro.Attributes = new Dictionary<string, object>();
69+
foreach (var attr in attributes)
70+
AddAttribute(entity, ro, attr);
6371
}
6472

6573
private void AddAttribute(IIdentifiable entity, ResourceObject ro, AttrAttribute attr)
@@ -76,7 +84,10 @@ private void AddAttribute(IIdentifiable entity, ResourceObject ro, AttrAttribute
7684
/// Depending on the requirements of the implementation (server or client serializer),
7785
/// this may be overridden.
7886
/// </summary>
79-
protected abstract RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable entity);
87+
protected virtual RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable entity)
88+
{
89+
return new RelationshipEntry { Data = GetRelatedResourceLinkage(relationship, entity) };
90+
}
8091

8192
protected object GetRelatedResourceLinkage(RelationshipAttribute relationship, IIdentifiable entity)
8293
{

src/JsonApiDotNetCore/Serialization/Server/Builders/IncludedResourceObjectBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace JsonApiDotNetCore.Serialization.Server.Builders
99
{
1010
/// <inheritdoc/>
11-
public class IncludedResourceObjectBuilder : BaseResourceObjectBuilder, IIncludedResourceObjectBuilder
11+
public class IncludedResourceObjectBuilder : ResourceObjectBuilder, IIncludedResourceObjectBuilder
1212
{
1313
private readonly HashSet<ResourceObject> _included;
1414
private readonly IFieldsToSerialize _fieldsToSerialize;

src/JsonApiDotNetCore/Serialization/Server/Builders/ResponseResourceObjectBuilder.cs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace JsonApiDotNetCore.Serialization.Server
99
{
10-
public class ResponseResourceObjectBuilder : BaseResourceObjectBuilder, IResourceObjectBuilder
10+
public class ResponseResourceObjectBuilder : ResourceObjectBuilder, IResourceObjectBuilder
1111
{
1212
private readonly IIncludedResourceObjectBuilder _includedBuilder;
1313
private readonly IIncludeService _includeService;
@@ -27,7 +27,6 @@ public ResponseResourceObjectBuilder(ILinkBuilder linkBuilder,
2727
_includeService = includeService;
2828
}
2929

30-
3130
public RelationshipEntry Build(IIdentifiable entity, RelationshipAttribute requestRelationship)
3231
{
3332
_requestRelationship = requestRelationship;
@@ -43,28 +42,25 @@ public RelationshipEntry Build(IIdentifiable entity, RelationshipAttribute reque
4342
/// </summary>
4443
protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable entity)
4544
{
46-
RelationshipEntry relationshipData = new RelationshipEntry();
47-
if (relationship == _requestRelationship)
48-
{ // if serializing a request with a requestRelationship, always populate the data field.
49-
relationshipData.Data = GetRelatedResourceLinkage(relationship, entity);
50-
}
51-
else if (ShouldInclude(relationship, out var relationshipChains))
52-
{ // if the relationship is included, populate the "data" field.
53-
relationshipData.Data = GetRelatedResourceLinkage(relationship, entity);
54-
if (relationshipData.HasResource)
45+
RelationshipEntry relationshipEntry = null;
46+
List<List<RelationshipAttribute>> relationshipChains = null;
47+
if (relationship == _requestRelationship || ShouldInclude(relationship, out relationshipChains ))
48+
{
49+
relationshipEntry = base.GetRelationshipData(relationship, entity);
50+
if (relationshipChains != null && relationshipEntry.HasResource)
5551
foreach (var chain in relationshipChains)
56-
// traverses (recursively) and extracts all (nested) related entities for the current inclusion chain.
52+
// traverses (recursively) and extracts all (nested) related entities for the current inclusion chain.
5753
_includedBuilder.IncludeRelationshipChain(chain, entity);
5854
}
5955

6056
var links = _linkBuilder.GetRelationshipLinks(relationship, entity);
6157
if (links != null)
6258
// if links relationshiplinks should be built for this entry, populate the "links" field.
63-
relationshipData.Links = links;
59+
(relationshipEntry = relationshipEntry ?? new RelationshipEntry()).Links = links;
6460

6561
/// if neither "links" nor "data" was popupated, return null, which will omit this entry from the output.
6662
/// (see the NullValueHandling settings on <see cref="ResourceObject"/>)
67-
return (relationshipData.IsPopulated || relationshipData.Links != null) ? relationshipData : null;
63+
return relationshipEntry;
6864
}
6965

7066
/// <summary>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
namespace JsonApiDotNetCore.Serialization.Server
2+
{
3+
public interface IResponseResourceObjectBuilder : IResourceObjectBuilder { }
4+
}

src/JsonApiDotNetCore/Serialization/Server/ResponseSerializer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace JsonApiDotNetCore.Serialization.Server
1414
{
15+
1516
/// <summary>
1617
/// Server serializer implementation of <see cref="BaseDocumentBuilder"/>
1718
/// </summary>
@@ -40,7 +41,7 @@ public ResponseSerializer(IMetaBuilder<TResource> metaBuilder,
4041
ILinkBuilder linkBuilder,
4142
IIncludedResourceObjectBuilder includedBuilder,
4243
IFieldsToSerialize fieldsToSerialize,
43-
ResponseResourceObjectBuilder resourceObjectBuilder,
44+
IResourceObjectBuilder resourceObjectBuilder,
4445
IContextEntityProvider provider) :
4546
base(resourceObjectBuilder, provider)
4647
{

test/UnitTests/Serialization/Client/RequestSerializerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class RequestSerializerTests : SerializerTestsSetup
1414

1515
public RequestSerializerTests()
1616
{
17-
var builder = new RequestResourceObjectBuilder(_resourceGraph, _resourceGraph);
17+
var builder = new ResourceObjectBuilder(_resourceGraph, _resourceGraph, new ResourceObjectBuilderSettings());
1818
_serializer = new RequestSerializer(_fieldExplorer, _resourceGraph, builder);
1919
}
2020

test/UnitTests/Serialization/Common/DocumentParserTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public void DeserializeResourceIdentifiers_SingleData_CanDeserialize()
3636

3737
// assert
3838
Assert.Equal(1, result.Id);
39-
4039
}
4140

4241
[Fact]

test/UnitTests/Serialization/Common/BaseResourceObjectBuilderTests.cs renamed to test/UnitTests/Serialization/Common/ResourceObjectBuilderTests.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using JsonApiDotNetCore.Models;
6+
using JsonApiDotNetCore.Serialization;
67
using Xunit;
78

89
namespace UnitTests.Serialization.Serializer
910
{
10-
public class BaseResourceObjectBuilderTests : SerializerTestsSetup
11+
public class ResourceObjectBuilderTests : SerializerTestsSetup
1112
{
12-
private readonly TestResourceObjectBuilder _builder;
13+
private readonly ResourceObjectBuilder _builder;
1314

14-
public BaseResourceObjectBuilderTests()
15+
public ResourceObjectBuilderTests()
1516
{
16-
_builder = new TestResourceObjectBuilder(_resourceGraph, _resourceGraph);
17+
_builder = new ResourceObjectBuilder(_resourceGraph, _resourceGraph, new ResourceObjectBuilderSettings());
1718
}
1819

1920
[Fact]

test/UnitTests/Serialization/SerializerTestsSetup.cs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -134,28 +134,7 @@ public TestDocumentBuilder(IResourceObjectBuilder resourceObjectBuilder, IContex
134134

135135
public new Document Build(IEnumerable entities, List<AttrAttribute> attributes = null, List<RelationshipAttribute> relationships = null)
136136
{
137-
return base.Build(entities, attributes ?? null, relationships ?? null) ;
138-
}
139-
}
140-
141-
142-
143-
/// <summary>
144-
/// Minimal implementation of abstract JsonApiSerializer base class, with
145-
/// the purpose of testing the business logic for building the document structure.
146-
/// </summary>
147-
protected class TestResourceObjectBuilder : BaseResourceObjectBuilder
148-
{
149-
public TestResourceObjectBuilder(IResourceGraph resourceGraph, IContextEntityProvider provider) : base(resourceGraph, provider, new ResourceObjectBuilderSettings()) { }
150-
151-
public new ResourceObject Build(IIdentifiable entity, IEnumerable<AttrAttribute> attributes = null, IEnumerable<RelationshipAttribute> relationships = null)
152-
{
153-
return base.Build(entity, attributes ?? new List<AttrAttribute>(), relationships ?? new List<RelationshipAttribute>());
154-
}
155-
156-
protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable entity)
157-
{
158-
return new RelationshipEntry { Data = GetRelatedResourceLinkage(relationship, entity) };
137+
return base.Build(entities, attributes ?? null, relationships ?? null);
159138
}
160139
}
161140
}

0 commit comments

Comments
 (0)