Skip to content

Commit dc93177

Browse files
committed
refactor: move methods into documentbuilder
1 parent fd7f903 commit dc93177

File tree

6 files changed

+142
-121
lines changed

6 files changed

+142
-121
lines changed

JsonApiDotNetCore/Abstractions/JsonApiContext.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using JsonApiDotNetCore.Configuration;
33
using JsonApiDotNetCore.Routing;
44
using Microsoft.AspNetCore.Http;
5+
using System.Linq;
6+
using JsonApiDotNetCore.Extensions;
57

68
namespace JsonApiDotNetCore.Abstractions
79
{
@@ -24,5 +26,17 @@ public Type GetJsonApiResourceType()
2426
{
2527
return Configuration.ResourceMapDefinitions[Route.BaseModelType];
2628
}
29+
30+
public string GetEntityName()
31+
{
32+
return (!(Route is RelationalRoute) ? Route.BaseRouteDefinition.ContextPropertyName
33+
: Configuration.Routes.Single(r => r.ModelType == ((RelationalRoute)Route).RelationalType).ContextPropertyName).ToCamelCase();
34+
}
35+
36+
public Type GetEntityType()
37+
{
38+
return !(Route is RelationalRoute) ? Route.BaseRouteDefinition.ModelType
39+
: ((RelationalRoute)Route).RelationalType;
40+
}
2741
}
2842
}

JsonApiDotNetCore/Abstractions/ModelAccessor.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
using System;
2-
using System.Collections;
3-
using System.ComponentModel;
42
using System.Linq;
5-
using System.Linq.Expressions;
63
using System.Reflection;
7-
using JsonApiDotNetCore.Attributes;
84
using JsonApiDotNetCore.Extensions;
95

106
namespace JsonApiDotNetCore.Abstractions
Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,100 @@
1-
using System.Collections.Generic;
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Linq;
5+
using System.Reflection;
6+
using JsonApiDotNetCore.Abstractions;
7+
using JsonApiDotNetCore.Attributes;
8+
using JsonApiDotNetCore.Extensions;
29

310
namespace JsonApiDotNetCore.JsonApi
411
{
5-
public static class DocumentBuilder
12+
public class DocumentBuilder
613
{
7-
public static Dictionary<string, string> BuildSelfLink(string protocol, string host, string nameSpace, string resourceCollectionName, string resourceId)
14+
private readonly JsonApiContext _context;
15+
private readonly object _resource;
16+
17+
public DocumentBuilder(JsonApiContext context, object resource)
18+
{
19+
_context = context;
20+
_resource = resource;
21+
}
22+
23+
public Dictionary<string, string> GetJsonApiDocumentLinks()
24+
{
25+
var request = _context.HttpContext.Request;
26+
27+
return new Dictionary<string, string> {
28+
{
29+
"self", $"{request.Scheme}://{request.Host}{request.Path}"
30+
}
31+
};
32+
}
33+
34+
public object GetJsonApiDocumentData()
35+
{
36+
var enumerableResult = _resource as IEnumerable;
37+
38+
if (enumerableResult == null) return ResourceToJsonApiDatum(EntityToJsonApiResource(_resource));
39+
40+
var data = new List<JsonApiDatum>();
41+
foreach (var resource in enumerableResult)
42+
{
43+
data.Add(ResourceToJsonApiDatum(EntityToJsonApiResource(resource)));
44+
}
45+
return data;
46+
}
47+
48+
private IJsonApiResource EntityToJsonApiResource(object entity)
49+
{
50+
var resource = entity as IJsonApiResource;
51+
if (resource != null) return resource;
52+
53+
var attributes = TypeDescriptor.GetAttributes(_resource);
54+
var type = ((JsonApiResourceAttribute)attributes[typeof(JsonApiResourceAttribute)]).JsonApiResourceType;
55+
return (IJsonApiResource)_context.Configuration.ResourceMapper.Map(_resource, _resource.GetType(), type);
56+
}
57+
58+
private JsonApiDatum ResourceToJsonApiDatum(IJsonApiResource resource)
59+
{
60+
return new JsonApiDatum
61+
{
62+
Type = _context.GetEntityName(),
63+
Id = resource.Id,
64+
Attributes = GetAttributesFromResource(resource),
65+
Links = GetJsonApiDatumLinks(resource),
66+
Relationships = BuildRelationshipsObject(resource)
67+
};
68+
}
69+
70+
private Dictionary<string, object> BuildRelationshipsObject(IJsonApiResource resource)
71+
{
72+
var relationships = new Dictionary<string, object>();
73+
_context.GetEntityType().GetProperties().Where(propertyInfo => propertyInfo.GetMethod.IsVirtual).ToList().ForEach(
74+
virtualProperty =>
75+
{
76+
relationships.Add(virtualProperty.Name, GetRelationshipLinks(resource, virtualProperty.Name.ToCamelCase()));
77+
});
78+
return relationships;
79+
}
80+
81+
private Dictionary<string, object> GetAttributesFromResource(IJsonApiResource resource)
82+
{
83+
return resource.GetType().GetProperties()
84+
.Where(propertyInfo => propertyInfo.GetMethod.IsVirtual == false)
85+
.ToDictionary(
86+
propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(resource)
87+
);
88+
}
89+
90+
private Dictionary<string, string> GetJsonApiDatumLinks(IJsonApiResource resource)
91+
{
92+
return BuildSelfLink(_context.HttpContext.Request.Scheme,
93+
_context.HttpContext.Request.Host.ToString(), _context.Configuration.Namespace,
94+
_context.GetEntityName(), resource.Id);
95+
}
96+
97+
private Dictionary<string, string> BuildSelfLink(string protocol, string host, string nameSpace, string resourceCollectionName, string resourceId)
898
{
999
var id = resourceId != null ? $"/{resourceId}" : string.Empty;
10100
return new Dictionary<string, string>
@@ -15,13 +105,20 @@ public static Dictionary<string, string> BuildSelfLink(string protocol, string h
15105
};
16106
}
17107

18-
public static Dictionary<string, string> BuildRelationshipLinks(string protocol, string host, string nameSpace, string resourceCollectionName, string resourceId, string relationshipName)
108+
private Dictionary<string, string> BuildRelationshipLinks(string protocol, string host, string nameSpace, string resourceCollectionName, string resourceId, string relationshipName)
19109
{
20110
return new Dictionary<string, string>
21111
{
22112
{"self", $"{protocol}://{host}/{nameSpace}/{resourceCollectionName}/{resourceId}/relationships/{relationshipName}"},
23113
{"related", $"{protocol}://{host}/{nameSpace}/{resourceCollectionName}/{resourceId}/{relationshipName}"}
24114
};
25115
}
116+
117+
private Dictionary<string, string> GetRelationshipLinks(IJsonApiResource resource, string relationshipName)
118+
{
119+
return BuildRelationshipLinks(_context.HttpContext.Request.Scheme,
120+
_context.HttpContext.Request.Host.ToString(), _context.Configuration.Namespace,
121+
_context.GetEntityName(), resource.Id, relationshipName);
122+
}
26123
}
27124
}

JsonApiDotNetCore/Routing/Router.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private ObjectResult ActivateControllerMethod(JsonApiController controller)
6868

6969
private object SerializeResult(object result)
7070
{
71-
return result == null ? null : new JsonApiSerializer(_jsonApiContext, _jsonApiModelConfiguration).ToJsonApiDocument(result);
71+
return result == null ? null : new JsonApiSerializer(_jsonApiContext).ToJsonApiDocument(result);
7272
}
7373

7474
private void SendResponse(ObjectResult result)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using JsonApiDotNetCore.Abstractions;
3+
using JsonApiDotNetCore.Configuration;
4+
5+
namespace JsonApiDotNetCore.Services
6+
{
7+
public class JsonApiDeserializer
8+
{
9+
private readonly JsonApiContext _context;
10+
private readonly JsonApiModelConfiguration _jsonApiModelConfiguration;
11+
private readonly string _entityName;
12+
private readonly Type _entityType;
13+
public JsonApiDeserializer(JsonApiContext jsonApiContext, JsonApiModelConfiguration configuration)
14+
{
15+
_context = jsonApiContext;
16+
_jsonApiModelConfiguration = configuration;
17+
_entityName = jsonApiContext.GetEntityName();
18+
_entityType = jsonApiContext.GetEntityType();
19+
}
20+
}
21+
}
Lines changed: 5 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,32 @@
1-
using System;
2-
using System.Collections;
3-
using System.Collections.Generic;
4-
using System.ComponentModel;
5-
using System.Linq;
6-
using JsonApiDotNetCore.Abstractions;
7-
using JsonApiDotNetCore.Attributes;
8-
using JsonApiDotNetCore.Configuration;
9-
using JsonApiDotNetCore.Extensions;
1+
using JsonApiDotNetCore.Abstractions;
102
using JsonApiDotNetCore.JsonApi;
113
using Newtonsoft.Json;
124
using Newtonsoft.Json.Serialization;
13-
using System.Reflection;
14-
using JsonApiDotNetCore.Routing;
155

166
namespace JsonApiDotNetCore.Services
177
{
188
public class JsonApiSerializer
199
{
2010
private readonly JsonApiContext _context;
21-
private readonly JsonApiModelConfiguration _jsonApiModelConfiguration;
22-
private string _entityName;
23-
private Type _entityType;
2411

25-
public JsonApiSerializer(JsonApiContext jsonApiContext, JsonApiModelConfiguration configuration)
12+
public JsonApiSerializer(JsonApiContext jsonApiContext)
2613
{
2714
_context = jsonApiContext;
28-
_jsonApiModelConfiguration = configuration;
29-
_entityName = GetEntityName();
30-
_entityType = GetEntityType();
31-
}
32-
33-
private string GetEntityName() {
34-
return (!(_context.Route is RelationalRoute) ? _context.Route.BaseRouteDefinition.ContextPropertyName
35-
: _jsonApiModelConfiguration.Routes.Single(r=> r.ModelType == ((RelationalRoute)_context.Route).RelationalType).ContextPropertyName).ToCamelCase();
36-
}
37-
38-
private Type GetEntityType() {
39-
return !(_context.Route is RelationalRoute) ? _context.Route.BaseRouteDefinition.ModelType
40-
: ((RelationalRoute)_context.Route).RelationalType;
4115
}
4216

4317
public string ToJsonApiDocument(object resultValue)
4418
{
19+
var documentBuilder = new DocumentBuilder(_context, resultValue);
4520
var response = new JsonApiDocument
4621
{
47-
Links = GetJsonApiDocumentLinks(_context),
48-
Data = GetJsonApiDocumentData(_context, resultValue)
22+
Links = documentBuilder.GetJsonApiDocumentLinks(),
23+
Data = documentBuilder.GetJsonApiDocumentData()
4924
};
5025

5126
return JsonConvert.SerializeObject(response, new JsonSerializerSettings
5227
{
5328
ContractResolver = new CamelCasePropertyNamesContractResolver()
5429
});
5530
}
56-
57-
private object GetJsonApiDocumentData(JsonApiContext context, object result)
58-
{
59-
var enumerableResult = result as IEnumerable;
60-
61-
if (enumerableResult == null) return ResourceToJsonApiDatum(context, EntityToJsonApiResource(result));
62-
63-
var data = new List<JsonApiDatum>();
64-
foreach (var resource in enumerableResult)
65-
{
66-
data.Add(ResourceToJsonApiDatum(context, EntityToJsonApiResource(resource)));
67-
}
68-
return data;
69-
}
70-
71-
private IJsonApiResource EntityToJsonApiResource(object entity)
72-
{
73-
var resource = entity as IJsonApiResource;
74-
if (resource != null) return resource;
75-
76-
var attributes = TypeDescriptor.GetAttributes(entity);
77-
var type = ((JsonApiResourceAttribute)attributes[typeof(JsonApiResourceAttribute)]).JsonApiResourceType;
78-
return (IJsonApiResource)_jsonApiModelConfiguration.ResourceMapper.Map(entity, entity.GetType(), type);
79-
}
80-
81-
private JsonApiDatum ResourceToJsonApiDatum(JsonApiContext context, IJsonApiResource resource)
82-
{
83-
return new JsonApiDatum
84-
{
85-
Type = _entityName,
86-
Id = resource.Id,
87-
Attributes = GetAttributesFromResource(resource),
88-
Links = GetJsonApiDatumLinks(context, resource),
89-
Relationships = BuildRelationshipsObject(context, resource)
90-
};
91-
}
92-
93-
private static Dictionary<string, object> GetAttributesFromResource(IJsonApiResource resource)
94-
{
95-
return resource.GetType().GetProperties()
96-
.Where(propertyInfo => propertyInfo.GetMethod.IsVirtual == false)
97-
.ToDictionary(
98-
propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(resource)
99-
);
100-
}
101-
102-
private Dictionary<string, string> GetJsonApiDocumentLinks(JsonApiContext jsonApiContext)
103-
{
104-
var request = jsonApiContext.HttpContext.Request;
105-
var route = jsonApiContext.Route;
106-
107-
return new Dictionary<string, string> {
108-
{
109-
"self", $"{request.Scheme}://{request.Host}{request.Path}"
110-
}
111-
};
112-
}
113-
114-
private Dictionary<string, string> GetJsonApiDatumLinks(JsonApiContext jsonApiContext, IJsonApiResource resource)
115-
{
116-
return DocumentBuilder.BuildSelfLink(jsonApiContext.HttpContext.Request.Scheme,
117-
jsonApiContext.HttpContext.Request.Host.ToString(), _jsonApiModelConfiguration.Namespace,
118-
_entityName, resource.Id);
119-
}
120-
121-
private Dictionary<string, object> BuildRelationshipsObject(JsonApiContext jsonApiContext, IJsonApiResource resource)
122-
{
123-
var relationships = new Dictionary<string, object>();
124-
_entityType.GetProperties().Where(propertyInfo => propertyInfo.GetMethod.IsVirtual).ToList().ForEach(
125-
virtualProperty =>
126-
{
127-
relationships.Add(virtualProperty.Name, GetRelationshipLinks(jsonApiContext, resource, virtualProperty.Name.ToCamelCase()));
128-
});
129-
return relationships;
130-
}
131-
132-
private Dictionary<string, string> GetRelationshipLinks(JsonApiContext jsonApiContext, IJsonApiResource resource, string relationshipName)
133-
{
134-
return DocumentBuilder.BuildRelationshipLinks(jsonApiContext.HttpContext.Request.Scheme,
135-
jsonApiContext.HttpContext.Request.Host.ToString(), _jsonApiModelConfiguration.Namespace,
136-
_entityName, resource.Id, relationshipName);
137-
}
13831
}
13932
}

0 commit comments

Comments
 (0)