Skip to content

Commit 50cfa8d

Browse files
authored
Merge pull request #254 from json-api-dotnet/fix/#237
De-Couple deserializer from GenericProcessorFactory
2 parents b6bbbdb + 01181dd commit 50cfa8d

23 files changed

+848
-427
lines changed

src/JsonApiDotNetCore/Builders/DocumentBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public DocumentData GetData(ContextEntity contextEntity, IIdentifiable entity)
107107
Id = entity.StringId
108108
};
109109

110-
if (_jsonApiContext.IsRelationshipData)
110+
if (_jsonApiContext.IsRelationshipPath)
111111
return data;
112112

113113
data.Attributes = new Dictionary<string, object>();

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,29 @@ public virtual async Task<TEntity> GetAndIncludeAsync(TId id, string relationshi
8484

8585
public virtual async Task<TEntity> CreateAsync(TEntity entity)
8686
{
87+
AttachHasManyPointers();
8788
_dbSet.Add(entity);
89+
8890
await _context.SaveChangesAsync();
8991
return entity;
9092
}
9193

94+
/// <summary>
95+
/// This is used to allow creation of HasMany relationships when the
96+
/// dependent side of the relationship already exists.
97+
/// </summary>
98+
private void AttachHasManyPointers()
99+
{
100+
var relationships = _jsonApiContext.HasManyRelationshipPointers.Get();
101+
foreach(var relationship in relationships)
102+
{
103+
foreach(var pointer in relationship.Value)
104+
{
105+
_context.Entry(pointer).State = EntityState.Unchanged;
106+
}
107+
}
108+
}
109+
92110
public virtual async Task<TEntity> UpdateAsync(TId id, TEntity entity)
93111
{
94112
var oldEntity = await GetAsync(id);

src/JsonApiDotNetCore/Data/IEntityRepository.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
3-
using System.Threading.Tasks;
4-
using JsonApiDotNetCore.Internal.Query;
51
using JsonApiDotNetCore.Models;
62

73
namespace JsonApiDotNetCore.Data
Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
1-
using Microsoft.EntityFrameworkCore;
21
using System;
2+
using Microsoft.EntityFrameworkCore;
33

44
namespace JsonApiDotNetCore.Extensions
55
{
66
public static class DbContextExtensions
77
{
8-
public static DbSet<T> GetDbSet<T>(this DbContext context) where T : class
9-
{
10-
var contextProperties = context.GetType().GetProperties();
11-
foreach(var property in contextProperties)
12-
{
13-
if (property.PropertyType == typeof(DbSet<T>))
14-
return (DbSet<T>)property.GetValue(context);
15-
}
16-
17-
throw new ArgumentException($"DbSet of type {typeof(T).FullName} not found on the DbContext", nameof(T));
18-
}
8+
[Obsolete("This is no longer required since the introduction of context.Set<T>", error: false)]
9+
public static DbSet<T> GetDbSet<T>(this DbContext context) where T : class
10+
=> context.Set<T>();
1911
}
2012
}

src/JsonApiDotNetCore/Extensions/TypeExtensions.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,28 @@ public static Type GetElementType(this IEnumerable enumerable)
3131

3232
return elementType;
3333
}
34+
35+
/// <summary>
36+
/// Creates a List{TInterface} where TInterface is the generic for type specified by t
37+
/// </summary>
38+
public static IEnumerable GetEmptyCollection(this Type t)
39+
{
40+
if (t == null) throw new ArgumentNullException(nameof(t));
41+
42+
var listType = typeof(List<>).MakeGenericType(t);
43+
var list = (IEnumerable)Activator.CreateInstance(listType);
44+
return list;
45+
}
46+
47+
/// <summary>
48+
/// Creates a new instance of type t, casting it to the specified TInterface
49+
/// </summary>
50+
public static TInterface New<TInterface>(this Type t)
51+
{
52+
if (t == null) throw new ArgumentNullException(nameof(t));
53+
54+
var instance = (TInterface)Activator.CreateInstance(t);
55+
return instance;
56+
}
3457
}
3558
}

src/JsonApiDotNetCore/Internal/TypeHelper.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ namespace JsonApiDotNetCore.Internal
77
{
88
public static class TypeHelper
99
{
10+
public static IList ConvertCollection(IEnumerable<object> collection, Type targetType)
11+
{
12+
var list = Activator.CreateInstance(typeof(List<>).MakeGenericType(targetType)) as IList;
13+
foreach(var item in collection)
14+
list.Add(ConvertType(item, targetType));
15+
return list;
16+
}
17+
1018
public static object ConvertType(object value, Type type)
1119
{
1220
if (value == null)

src/JsonApiDotNetCore/JsonApiDotNetCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<VersionPrefix>2.2.4</VersionPrefix>
3+
<VersionPrefix>2.2.5</VersionPrefix>
44
<TargetFrameworks>$(NetStandardVersion)</TargetFrameworks>
55
<AssemblyName>JsonApiDotNetCore</AssemblyName>
66
<PackageId>JsonApiDotNetCore</PackageId>

src/JsonApiDotNetCore/Models/HasManyAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public override void SetValue(object entity, object newValue)
1212
.GetType()
1313
.GetProperty(InternalRelationshipName);
1414

15-
propertyInfo.SetValue(entity, newValue);
15+
propertyInfo.SetValue(entity, newValue);
1616
}
1717
}
1818
}

src/JsonApiDotNetCore/Models/HasOneAttribute.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,14 @@ public HasOneAttribute(string publicName, Link documentLinks = Link.All, bool ca
3939
? $"{InternalRelationshipName}Id"
4040
: _explicitIdentifiablePropertyName;
4141

42+
/// <summary>
43+
/// Sets the value of the property identified by this attribute
44+
/// </summary>
45+
/// <param name="entity">The target object</param>
46+
/// <param name="newValue">The new property value</param>
4247
public override void SetValue(object entity, object newValue)
4348
{
44-
var propertyName = (newValue.GetType() == Type)
49+
var propertyName = (newValue?.GetType() == Type)
4550
? InternalRelationshipName
4651
: IdentifiablePropertyName;
4752

src/JsonApiDotNetCore/Models/RelationshipAttribute.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,28 @@ protected RelationshipAttribute(string publicName, Link documentLinks, bool canI
1919
public Link DocumentLinks { get; } = Link.All;
2020
public bool CanInclude { get; }
2121

22+
public bool TryGetHasOne(out HasOneAttribute result)
23+
{
24+
if (IsHasOne)
25+
{
26+
result = (HasOneAttribute)this;
27+
return true;
28+
}
29+
result = null;
30+
return false;
31+
}
32+
33+
public bool TryGetHasMany(out HasManyAttribute result)
34+
{
35+
if (IsHasMany)
36+
{
37+
result = (HasManyAttribute)this;
38+
return true;
39+
}
40+
result = null;
41+
return false;
42+
}
43+
2244
public abstract void SetValue(object entity, object newValue);
2345

2446
public override string ToString()

0 commit comments

Comments
 (0)