Skip to content

Commit d64709e

Browse files
committed
first pass at pointer replacement and service location
1 parent 24e7a99 commit d64709e

23 files changed

+228
-28
lines changed

src/JsonApiDotNetCore/Builders/ContextGraphBuilder.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ public IContextGraph Build()
2828
return graph;
2929
}
3030

31-
public void AddResource<TResource>(string pluralizedTypeName) where TResource : class
31+
public void AddResource<TResource>(string pluralizedTypeName) where TResource : class, IIdentifiable<int>
32+
=> AddResource<TResource, int>(pluralizedTypeName);
33+
34+
public void AddResource<TResource, TId>(string pluralizedTypeName) where TResource : class, IIdentifiable<TId>
3235
{
3336
var entityType = typeof(TResource);
3437

@@ -38,6 +41,7 @@ public void AddResource<TResource>(string pluralizedTypeName) where TResource :
3841
{
3942
EntityName = pluralizedTypeName,
4043
EntityType = entityType,
44+
IdentityType = typeof(TId),
4145
Attributes = GetAttributes(entityType),
4246
Relationships = GetRelationships(entityType)
4347
});

src/JsonApiDotNetCore/Builders/IContextGraphBuilder.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ public interface IContextGraphBuilder
88
{
99
Link DocumentLinks { get; set; }
1010
IContextGraph Build();
11-
void AddResource<TResource>(string pluralizedTypeName) where TResource : class;
11+
void AddResource<TResource>(string pluralizedTypeName) where TResource : class, IIdentifiable<int>;
12+
void AddResource<TResource, TId>(string pluralizedTypeName) where TResource : class, IIdentifiable<TId>;
1213
void AddDbContext<T>() where T : DbContext;
1314
}
1415
}

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public virtual async Task<TEntity> UpdateAsync(TId id, TEntity entity)
137137

138138
public async Task UpdateRelationshipsAsync(object parent, RelationshipAttribute relationship, IEnumerable<string> relationshipIds)
139139
{
140-
var genericProcessor = _genericProcessorFactory.GetProcessor(relationship.Type);
140+
var genericProcessor = _genericProcessorFactory.GetProcessor<IGenericProcessor>(relationship.Type);
141141
await genericProcessor.UpdateRelationshipsAsync(parent, relationship, relationshipIds);
142142
}
143143

src/JsonApiDotNetCore/Internal/ContextEntity.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class ContextEntity
88
{
99
public string EntityName { get; set; }
1010
public Type EntityType { get; set; }
11+
public Type IdentityType { get; set; }
1112
public List<AttrAttribute> Attributes { get; set; }
1213
public List<RelationshipAttribute> Relationships { get; set; }
1314
public Link Links { get; set; } = Link.All;
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
11
using System;
2-
using Microsoft.EntityFrameworkCore;
32

43
namespace JsonApiDotNetCore.Internal.Generics
54
{
65
public class GenericProcessorFactory : IGenericProcessorFactory
76
{
8-
private readonly DbContext _dbContext;
97
private readonly IServiceProvider _serviceProvider;
108

11-
public GenericProcessorFactory(DbContext dbContext,
12-
IServiceProvider serviceProvider)
9+
public GenericProcessorFactory(IServiceProvider serviceProvider)
1310
{
14-
_dbContext = dbContext;
1511
_serviceProvider = serviceProvider;
1612
}
1713

18-
public IGenericProcessor GetProcessor(Type type)
14+
public TInterface GetProcessor<TInterface>(Type[] types)
1915
{
20-
var processorType = typeof(GenericProcessor<>).MakeGenericType(type);
21-
return (IGenericProcessor)_serviceProvider.GetService(processorType);
16+
var processorType = typeof(GenericProcessor<>).MakeGenericType(types);
17+
return (TInterface)_serviceProvider.GetService(processorType);
2218
}
2319
}
2420
}

src/JsonApiDotNetCore/Internal/Generics/IGenericProcessorFactory.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ namespace JsonApiDotNetCore.Internal.Generics
55
/// <summary>
66
/// Used to generate a generic operations processor when the types
77
/// are not know until runtime. The typical use case would be for
8+
/// accessing relationship data.be for
89
/// accessing relationship data.
910
/// </summary>
1011
public interface IGenericProcessorFactory
1112
{
12-
IGenericProcessor GetProcessor(Type type);
13+
14+
TInterface GetProcessor<TInterface>(params Type[] types);
1315
}
1416
}
Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,63 @@
11
using System.Collections.Generic;
2+
using JsonApiDotNetCore.Models.Pointers;
23
using Newtonsoft.Json;
4+
using Newtonsoft.Json.Linq;
5+
using Newtonsoft.Json.Schema;
36

47
namespace JsonApiDotNetCore.Models
58
{
69
public class DocumentData
710
{
811
[JsonProperty("type")]
9-
public string Type { get; set; }
12+
public object Type { get; set; }
1013

1114
[JsonProperty("id")]
12-
public string Id { get; set; }
15+
public object Id { get; set; }
1316

1417
[JsonProperty("attributes")]
1518
public Dictionary<string, object> Attributes { get; set; }
1619

1720
[JsonProperty("relationships")]
1821
public Dictionary<string, RelationshipData> Relationships { get; set; }
1922
}
23+
24+
public class DocumentDataPointerReplacement<TPointer, TPointerBase>
25+
where TPointer : Pointer<TPointerBase>, new()
26+
{
27+
private readonly DocumentData _data;
28+
29+
public DocumentDataPointerReplacement(DocumentData data)
30+
{
31+
_data = data;
32+
}
33+
34+
public void ReplacePointers(List<TPointerBase> parentDoc)
35+
{
36+
ReplacePointer(_data.Id, parentDoc);
37+
ReplacePointer(_data.Type, parentDoc);
38+
}
39+
40+
private void ReplacePointer(object reference, List<TPointerBase> parentDoc)
41+
{
42+
if (reference is JObject jObj)
43+
if (jObj.TryParse<TPointer, TPointerBase>(Pointer<TPointerBase>.JsonSchema, out Pointer<TPointerBase> pointer))
44+
reference = pointer.GetValue(parentDoc);
45+
}
46+
}
2047
}
48+
49+
public static class JObjectExtensions
50+
{
51+
public static bool TryParse<TPointer, TPointerBase>(this JObject obj, JSchema schema, out Pointer<TPointerBase> pointer)
52+
where TPointer : Pointer<TPointerBase>, new()
53+
{
54+
if (obj.IsValid(schema))
55+
{
56+
pointer = obj.ToObject<TPointer>();
57+
return true;
58+
}
59+
60+
pointer = null;
61+
return false;
62+
}
63+
}

src/JsonApiDotNetCore/Models/Operations/Operation.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,16 @@ private void SetData(object data)
4747
public bool DataIsList { get; private set; }
4848
public List<DocumentData> DataList { get; private set; }
4949
public DocumentData DataObject { get; private set; }
50+
51+
public string GetResourceTypeName()
52+
{
53+
if(Ref != null)
54+
return Ref.Type?.ToString();
55+
56+
if(DataIsList)
57+
return DataList[0].Type?.ToString();
58+
59+
return DataObject.Type?.ToString();
60+
}
5061
}
5162
}

src/JsonApiDotNetCore/Models/Pointers/OperationsPointer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace JsonApiDotNetCore.Models.Pointers
77
{
8-
public class OperationsPointer : Pointer
8+
public class OperationsPointer : Pointer<Operation>
99
{
1010
/// <exception cref="System.ArgumentNullException"></exception>
1111
/// <exception cref="System.ArgumentException"></exception>

src/JsonApiDotNetCore/Models/Pointers/Pointer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
namespace JsonApiDotNetCore.Models.Pointers
55
{
6-
public abstract class Pointer
6+
public abstract class Pointer<TPointerBase>
77
{
8-
private static JSchema JsonSchema { get; } = JSchema.Parse("{ 'pointer': {'type': 'string'} }");
8+
public static JSchema JsonSchema { get; } = JSchema.Parse("{ 'pointer': {'type': 'string'} }");
99

1010
/// <summary>
1111
/// Location represented by the pointer

0 commit comments

Comments
 (0)