Skip to content

Commit 0077cc1

Browse files
authored
Merge pull request #116 from Research-Institute/develop
Develop
2 parents 748ce06 + 5919517 commit 0077cc1

14 files changed

+324
-36
lines changed

docs/EntityRepositories.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,14 @@ A sample implementation that performs data authorization might look like:
2424
public class MyAuthorizedEntityRepository : DefaultEntityRepository<MyEntity>
2525
{
2626
private readonly ILogger _logger;
27-
private readonly AppDbContext _context;
2827
private readonly IAuthenticationService _authenticationService;
2928

30-
public MyAuthorizedEntityRepository(AppDbContext context,
29+
public MyAuthorizedEntityRepository(
3130
ILoggerFactory loggerFactory,
3231
IJsonApiContext jsonApiContext,
3332
IAuthenticationService authenticationService)
34-
: base(context, loggerFactory, jsonApiContext)
35-
{
36-
_context = context;
33+
: base(loggerFactory, jsonApiContext)
34+
{
3735
_logger = loggerFactory.CreateLogger<MyEntityRepository>();
3836
_authenticationService = authenticationService;
3937
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using JsonApiDotNetCore.Extensions;
3+
using Microsoft.EntityFrameworkCore;
4+
5+
namespace JsonApiDotNetCore.Data
6+
{
7+
public class DbContextResolver : IDbContextResolver
8+
{
9+
private readonly DbContext _context;
10+
11+
public DbContextResolver(DbContext context)
12+
{
13+
_context = context;
14+
}
15+
16+
public DbContext GetContext() => _context;
17+
18+
public DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
19+
=> _context.GetDbSet<TEntity>();
20+
}
21+
}

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

Lines changed: 23 additions & 4 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;
@@ -17,12 +18,19 @@ public class DefaultEntityRepository<TEntity>
1718
IEntityRepository<TEntity>
1819
where TEntity : class, IIdentifiable<int>
1920
{
21+
[Obsolete("DbContext is no longer directly injected into the ctor. Use JsonApiContext.GetDbContextResolver() instead")]
2022
public DefaultEntityRepository(
2123
DbContext context,
2224
ILoggerFactory loggerFactory,
2325
IJsonApiContext jsonApiContext)
2426
: base(context, loggerFactory, jsonApiContext)
2527
{ }
28+
29+
public DefaultEntityRepository(
30+
ILoggerFactory loggerFactory,
31+
IJsonApiContext jsonApiContext)
32+
: base(loggerFactory, jsonApiContext)
33+
{ }
2634
}
2735

2836
public class DefaultEntityRepository<TEntity, TId>
@@ -35,6 +43,7 @@ public class DefaultEntityRepository<TEntity, TId>
3543
private readonly IJsonApiContext _jsonApiContext;
3644
private readonly IGenericProcessorFactory _genericProcessorFactory;
3745

46+
[Obsolete("DbContext is no longer directly injected into the ctor. Use JsonApiContext.GetDbContextResolver() instead")]
3847
public DefaultEntityRepository(
3948
DbContext context,
4049
ILoggerFactory loggerFactory,
@@ -47,6 +56,18 @@ public DefaultEntityRepository(
4756
_genericProcessorFactory = _jsonApiContext.GenericProcessorFactory;
4857
}
4958

59+
public DefaultEntityRepository(
60+
ILoggerFactory loggerFactory,
61+
IJsonApiContext jsonApiContext)
62+
{
63+
var contextResolver = jsonApiContext.GetDbContextResolver();
64+
_context = contextResolver.GetContext();
65+
_dbSet = contextResolver.GetDbSet<TEntity>();
66+
_jsonApiContext = jsonApiContext;
67+
_logger = loggerFactory.CreateLogger<DefaultEntityRepository<TEntity, TId>>();
68+
_genericProcessorFactory = _jsonApiContext.GenericProcessorFactory;
69+
}
70+
5071
public virtual IQueryable<TEntity> Get()
5172
{
5273
if(_jsonApiContext.QuerySet?.Fields != null && _jsonApiContext.QuerySet.Fields.Any())
@@ -111,10 +132,8 @@ public virtual async Task<TEntity> UpdateAsync(TId id, TEntity entity)
111132
if (oldEntity == null)
112133
return null;
113134

114-
_jsonApiContext.RequestEntity.Attributes.ForEach(attr =>
115-
{
116-
attr.SetValue(oldEntity, attr.GetValue(entity));
117-
});
135+
foreach(var attr in _jsonApiContext.AttributesToUpdate)
136+
attr.Key.SetValue(oldEntity, attr.Value);
118137

119138
foreach(var relationship in _jsonApiContext.RelationshipsToUpdate)
120139
relationship.Key.SetValue(oldEntity, relationship.Value);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace JsonApiDotNetCore.Data
4+
{
5+
public interface IDbContextResolver
6+
{
7+
DbContext GetContext();
8+
DbSet<TEntity> GetDbSet<TEntity>()
9+
where TEntity : class;
10+
}
11+
}

src/JsonApiDotNetCore/Extensions/IServiceCollectionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public static void AddJsonApiInternals(
8989
services.AddSingleton<DbContextOptions>(new DbContextOptionsBuilder().Options);
9090
}
9191

92+
services.AddScoped<IDbContextResolver, DbContextResolver>();
9293
services.AddScoped(typeof(IEntityRepository<>), typeof(DefaultEntityRepository<>));
9394
services.AddScoped(typeof(IEntityRepository<,>), typeof(DefaultEntityRepository<,>));
9495
services.AddScoped(typeof(IResourceService<>), typeof(EntityResourceService<>));

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.0.6</VersionPrefix>
3+
<VersionPrefix>2.0.7</VersionPrefix>
44
<TargetFrameworks>netstandard1.6</TargetFrameworks>
55
<AssemblyName>JsonApiDotNetCore</AssemblyName>
66
<PackageId>JsonApiDotNetCore</PackageId>

src/JsonApiDotNetCore/Models/AttrAttribute.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ public AttrAttribute(string publicName)
1111
PublicAttributeName = publicName;
1212
}
1313

14+
public AttrAttribute(string publicName, string internalName)
15+
{
16+
PublicAttributeName = publicName;
17+
InternalAttributeName = internalName;
18+
}
19+
1420
public string PublicAttributeName { get; set; }
1521
public string InternalAttributeName { get; set; }
1622

src/JsonApiDotNetCore/Serialization/JsonApiDeSerializer.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public JsonApiDeSerializer(
2727
public object Deserialize(string requestBody)
2828
{
2929
var document = JsonConvert.DeserializeObject<Document>(requestBody);
30-
var entity = DataToObject(document.Data);
30+
var entity = DocumentToObject(document.Data);
3131
return entity;
3232
}
3333

@@ -46,30 +46,29 @@ public object DeserializeRelationship(string requestBody)
4646
return new List<DocumentData> { data.ToObject<DocumentData>() };
4747
}
4848

49-
5049
public List<TEntity> DeserializeList<TEntity>(string requestBody)
5150
{
5251
var documents = JsonConvert.DeserializeObject<Documents>(requestBody);
5352

5453
var deserializedList = new List<TEntity>();
5554
foreach (var data in documents.Data)
5655
{
57-
var entity = DataToObject(data);
56+
var entity = DocumentToObject(data);
5857
deserializedList.Add((TEntity)entity);
5958
}
6059

6160
return deserializedList;
6261
}
6362

64-
private object DataToObject(DocumentData data)
63+
private object DocumentToObject(DocumentData data)
6564
{
6665
var contextEntity = _jsonApiContext.ContextGraph.GetContextEntity(data.Type);
6766
_jsonApiContext.RequestEntity = contextEntity;
6867

6968
var entity = Activator.CreateInstance(contextEntity.EntityType);
7069

71-
entity = _setEntityAttributes(entity, contextEntity, data.Attributes);
72-
entity = _setRelationships(entity, contextEntity, data.Relationships);
70+
entity = SetEntityAttributes(entity, contextEntity, data.Attributes);
71+
entity = SetRelationships(entity, contextEntity, data.Relationships);
7372

7473
var identifiableEntity = (IIdentifiable)entity;
7574

@@ -79,7 +78,7 @@ private object DataToObject(DocumentData data)
7978
return identifiableEntity;
8079
}
8180

82-
private object _setEntityAttributes(
81+
private object SetEntityAttributes(
8382
object entity, ContextEntity contextEntity, Dictionary<string, object> attributeValues)
8483
{
8584
if (attributeValues == null || attributeValues.Count == 0)
@@ -99,13 +98,14 @@ private object _setEntityAttributes(
9998
{
10099
var convertedValue = TypeHelper.ConvertType(newValue, entityProperty.PropertyType);
101100
entityProperty.SetValue(entity, convertedValue);
101+
_jsonApiContext.AttributesToUpdate[attr] = convertedValue;
102102
}
103103
}
104104

105105
return entity;
106106
}
107107

108-
private object _setRelationships(
108+
private object SetRelationships(
109109
object entity,
110110
ContextEntity contextEntity,
111111
Dictionary<string, RelationshipData> relationships)
@@ -118,14 +118,14 @@ private object _setRelationships(
118118
foreach (var attr in contextEntity.Relationships)
119119
{
120120
entity = attr.IsHasOne
121-
? _setHasOneRelationship(entity, entityProperties, attr, contextEntity, relationships)
122-
: _setHasManyRelationship(entity, entityProperties, attr, contextEntity, relationships);
121+
? SetHasOneRelationship(entity, entityProperties, attr, contextEntity, relationships)
122+
: SetHasManyRelationship(entity, entityProperties, attr, contextEntity, relationships);
123123
}
124124

125125
return entity;
126126
}
127127

128-
private object _setHasOneRelationship(object entity,
128+
private object SetHasOneRelationship(object entity,
129129
PropertyInfo[] entityProperties,
130130
RelationshipAttribute attr,
131131
ContextEntity contextEntity,
@@ -158,7 +158,7 @@ private object _setHasOneRelationship(object entity,
158158
return entity;
159159
}
160160

161-
private object _setHasManyRelationship(object entity,
161+
private object SetHasManyRelationship(object entity,
162162
PropertyInfo[] entityProperties,
163163
RelationshipAttribute attr,
164164
ContextEntity contextEntity,

src/JsonApiDotNetCore/Services/IJsonApiContext.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using JsonApiDotNetCore.Builders;
33
using JsonApiDotNetCore.Configuration;
4+
using JsonApiDotNetCore.Data;
45
using JsonApiDotNetCore.Internal;
56
using JsonApiDotNetCore.Internal.Generics;
67
using JsonApiDotNetCore.Internal.Query;
@@ -22,6 +23,8 @@ public interface IJsonApiContext
2223
PageManager PageManager { get; set; }
2324
IMetaBuilder MetaBuilder { get; set; }
2425
IGenericProcessorFactory GenericProcessorFactory { get; set; }
26+
Dictionary<AttrAttribute, object> AttributesToUpdate { get; set; }
2527
Dictionary<RelationshipAttribute, object> RelationshipsToUpdate { get; set; }
28+
IDbContextResolver GetDbContextResolver();
2629
}
2730
}

src/JsonApiDotNetCore/Services/JsonApiContext.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Linq;
34
using JsonApiDotNetCore.Builders;
45
using JsonApiDotNetCore.Configuration;
6+
using JsonApiDotNetCore.Data;
57
using JsonApiDotNetCore.Internal;
68
using JsonApiDotNetCore.Internal.Generics;
79
using JsonApiDotNetCore.Internal.Query;
@@ -13,19 +15,22 @@ namespace JsonApiDotNetCore.Services
1315
public class JsonApiContext : IJsonApiContext
1416
{
1517
private readonly IHttpContextAccessor _httpContextAccessor;
18+
private readonly IDbContextResolver _contextResolver;
19+
1620
public JsonApiContext(
21+
IDbContextResolver contextResolver,
1722
IContextGraph contextGraph,
1823
IHttpContextAccessor httpContextAccessor,
1924
JsonApiOptions options,
2025
IMetaBuilder metaBuilder,
2126
IGenericProcessorFactory genericProcessorFactory)
2227
{
28+
_contextResolver = contextResolver;
2329
ContextGraph = contextGraph;
2430
_httpContextAccessor = httpContextAccessor;
2531
Options = options;
2632
MetaBuilder = metaBuilder;
2733
GenericProcessorFactory = genericProcessorFactory;
28-
RelationshipsToUpdate = new Dictionary<RelationshipAttribute, object>();
2934
}
3035

3136
public JsonApiOptions Options { get; set; }
@@ -39,16 +44,17 @@ public JsonApiContext(
3944
public PageManager PageManager { get; set; }
4045
public IMetaBuilder MetaBuilder { get; set; }
4146
public IGenericProcessorFactory GenericProcessorFactory { get; set; }
42-
public Dictionary<RelationshipAttribute, object> RelationshipsToUpdate { get; set; }
47+
public Dictionary<AttrAttribute, object> AttributesToUpdate { get; set; } = new Dictionary<AttrAttribute, object>();
48+
public Dictionary<RelationshipAttribute, object> RelationshipsToUpdate { get; set; } = new Dictionary<RelationshipAttribute, object>();
4349

4450
public IJsonApiContext ApplyContext<T>()
4551
{
4652
var context = _httpContextAccessor.HttpContext;
4753
var path = context.Request.Path.Value.Split('/');
4854

4955
RequestEntity = ContextGraph.GetContextEntity(typeof(T));
50-
51-
if(context.Request.Query.Any())
56+
57+
if (context.Request.Query.Any())
5258
{
5359
QuerySet = new QuerySet(this, context.Request.Query);
5460
IncludedRelationships = QuerySet.IncludedRelationships;
@@ -61,14 +67,17 @@ public IJsonApiContext ApplyContext<T>()
6167
return this;
6268
}
6369

70+
public IDbContextResolver GetDbContextResolver() => _contextResolver;
71+
6472
private PageManager GetPageManager()
6573
{
66-
if(Options.DefaultPageSize == 0 && (QuerySet == null || QuerySet.PageQuery.PageSize == 0))
74+
if (Options.DefaultPageSize == 0 && (QuerySet == null || QuerySet.PageQuery.PageSize == 0))
6775
return new PageManager();
68-
69-
var query = QuerySet?.PageQuery ?? new PageQuery();
7076

71-
return new PageManager {
77+
var query = QuerySet?.PageQuery ?? new PageQuery();
78+
79+
return new PageManager
80+
{
7281
DefaultPageSize = Options.DefaultPageSize,
7382
CurrentPage = query.PageOffset > 0 ? query.PageOffset : 1,
7483
PageSize = query.PageSize > 0 ? query.PageSize : Options.DefaultPageSize

0 commit comments

Comments
 (0)