Skip to content

Commit 664d35e

Browse files
committed
wrapping up basic testing and functionality
1 parent a208460 commit 664d35e

File tree

3 files changed

+56
-69
lines changed

3 files changed

+56
-69
lines changed

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Reflection;
45
using System.Threading.Tasks;
56
using JsonApiDotNetCore.Extensions;
67
using JsonApiDotNetCore.Internal;
@@ -75,9 +76,7 @@ public virtual async Task<TEntity> GetAndIncludeAsync(TId id, string relationshi
7576
{
7677
_logger.LogDebug($"[JADN] GetAndIncludeAsync({id}, {relationshipName})");
7778

78-
var result = await Get()
79-
.Include(relationshipName)
80-
.SingleOrDefaultAsync(e => e.Id.Equals(id));
79+
var result = await Include(Get(), relationshipName).SingleOrDefaultAsync(e => e.Id.Equals(id));
8180

8281
return result;
8382
}
@@ -178,7 +177,6 @@ public virtual IQueryable<TEntity> Include(IQueryable<TEntity> entities, string
178177
throw new JsonApiException(400, $"Including the relationship {relationshipName} on {entity.EntityName} is not allowed");
179178
}
180179
return entities.Include(relationship.InternalRelationshipName);
181-
182180
}
183181

184182
public virtual async Task<IEnumerable<TEntity>> PageAsync(IQueryable<TEntity> entities, int pageSize, int pageNumber)

src/JsonApiDotNetCore/Services/EntityResourceService.cs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,13 @@ public virtual async Task<object> GetRelationshipsAsync(TId id, string relations
8484

8585
public virtual async Task<object> GetRelationshipAsync(TId id, string relationshipName)
8686
{
87-
relationshipName = _jsonApiContext.ContextGraph
88-
.GetRelationshipName<T>(relationshipName);
89-
90-
if (relationshipName == null)
91-
throw new JsonApiException(422, "Relationship name not specified.");
92-
if (_logger.IsEnabled(LogLevel.Trace))
93-
{
94-
_logger.LogTrace($"Looking up '{relationshipName}'...");
95-
}
96-
9787
var entity = await _entities.GetAndIncludeAsync(id, relationshipName);
9888
// TODO: it would be better if we could distinguish whether or not the relationship was not found,
9989
// vs the relationship not being set on the instance of T
10090
if (entity == null)
10191
throw new JsonApiException(404, $"Relationship {relationshipName} not found.");
10292

103-
var relationship = _jsonApiContext.ContextGraph
104-
.GetRelationship(entity, relationshipName);
93+
var relationship = _jsonApiContext.ContextGraph.GetRelationship(entity, relationshipName);
10594

10695
return relationship;
10796
}
@@ -119,12 +108,6 @@ public virtual async Task<T> UpdateAsync(TId id, T entity)
119108

120109
public virtual async Task UpdateRelationshipsAsync(TId id, string relationshipName, List<DocumentData> relationships)
121110
{
122-
relationshipName = _jsonApiContext.ContextGraph
123-
.GetRelationshipName<T>(relationshipName);
124-
125-
if (relationshipName == null)
126-
throw new JsonApiException(422, "Relationship name not specified.");
127-
128111
var entity = await _entities.GetAndIncludeAsync(id, relationshipName);
129112

130113
if (entity == null)
@@ -133,7 +116,7 @@ public virtual async Task UpdateRelationshipsAsync(TId id, string relationshipNa
133116
var relationship = _jsonApiContext.ContextGraph
134117
.GetContextEntity(typeof(T))
135118
.Relationships
136-
.FirstOrDefault(r => r.InternalRelationshipName == relationshipName);
119+
.FirstOrDefault(r => r.PublicRelationshipName == relationshipName);
137120

138121
var relationshipIds = relationships.Select(r => r?.Id?.ToString());
139122

src/JsonApiDotNetCore/Services/MappingResourceService.cs

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
using System;
2+
using System.Collections;
13
using System.Collections.Generic;
24
using System.Linq;
5+
using System.Reflection;
36
using System.Threading.Tasks;
47
using AutoMapper;
58
using JsonApiDotNetCore.Data;
@@ -10,10 +13,10 @@
1013

1114
namespace JsonApiDotNetCore.Services
1215
{
13-
public class MappingResourceService<TDto, TEntity> :
14-
MappingResourceService<TDto, TEntity, int>,
15-
IResourceService<TDto>
16-
where TDto : class, IIdentifiable<int>
16+
public class MappingResourceService<TResource, TEntity>
17+
: MappingResourceService<TResource, TEntity, int>,
18+
IResourceService<TResource>
19+
where TResource : class, IIdentifiable<int>
1720
where TEntity : class, IIdentifiable<int>
1821
{
1922
public MappingResourceService(
@@ -25,8 +28,9 @@ public MappingResourceService(
2528
{ }
2629
}
2730

28-
public class MappingResourceService<TDto, TEntity, TId> : IResourceService<TDto, TId>
29-
where TDto : class, IIdentifiable<TId>
31+
public class MappingResourceService<TResource, TEntity, TId>
32+
: IResourceService<TResource, TId>
33+
where TResource : class, IIdentifiable<TId>
3034
where TEntity : class, IIdentifiable<TId>
3135
{
3236
private readonly IJsonApiContext _jsonApiContext;
@@ -42,11 +46,11 @@ public MappingResourceService(
4246
{
4347
_jsonApiContext = jsonApiContext;
4448
_entities = entityRepository;
45-
_logger = loggerFactory.CreateLogger<MappingResourceService<TDto, TEntity, TId>>();
49+
_logger = loggerFactory.CreateLogger<MappingResourceService<TResource, TEntity, TId>>();
4650
_mapper = mapper;
4751
}
4852

49-
public virtual async Task<IEnumerable<TDto>> GetAsync()
53+
public virtual async Task<IEnumerable<TResource>> GetAsync()
5054
{
5155
var entities = _entities.Get();
5256

@@ -63,90 +67,92 @@ public virtual async Task<IEnumerable<TDto>> GetAsync()
6367
return pagedEntities;
6468
}
6569

66-
public virtual async Task<TDto> GetAsync(TId id)
70+
public virtual async Task<TResource> GetAsync(TId id)
6771
{
68-
TDto entity;
72+
TResource dto;
6973
if (ShouldIncludeRelationships())
70-
entity = await GetWithRelationshipsAsync(id);
74+
dto = await GetWithRelationshipsAsync(id);
7175
else
72-
entity = _mapper.Map<TDto>(await _entities.GetAsync(id));
73-
return entity;
76+
{
77+
TEntity entity = await _entities.GetAsync(id);
78+
dto = _mapper.Map<TResource>(entity);
79+
}
80+
return dto;
7481
}
7582

7683
private bool ShouldIncludeRelationships()
7784
=> (_jsonApiContext.QuerySet?.IncludedRelationships != null && _jsonApiContext.QuerySet.IncludedRelationships.Count > 0);
7885

79-
private async Task<TDto> GetWithRelationshipsAsync(TId id)
86+
private async Task<TResource> GetWithRelationshipsAsync(TId id)
8087
{
8188
var query = _entities.Get().Where(e => e.Id.Equals(id));
8289
_jsonApiContext.QuerySet.IncludedRelationships.ForEach(r =>
8390
{
8491
query = _entities.Include(query, r);
8592
});
8693
var value = await _entities.FirstOrDefaultAsync(query);
87-
return _mapper.Map<TDto>(value);
94+
return _mapper.Map<TResource>(value);
8895
}
8996

9097
public virtual async Task<object> GetRelationshipsAsync(TId id, string relationshipName)
9198
=> await GetRelationshipAsync(id, relationshipName);
9299

93100
public virtual async Task<object> GetRelationshipAsync(TId id, string relationshipName)
94101
{
95-
relationshipName = _jsonApiContext.ContextGraph
96-
.GetRelationshipName<TDto>(relationshipName);
97-
98-
if (relationshipName == null)
99-
throw new JsonApiException(422, "Relationship name not specified.");
100-
if (_logger.IsEnabled(LogLevel.Trace))
101-
{
102-
_logger.LogTrace($"Looking up '{relationshipName}'...");
103-
}
104-
105102
var entity = await _entities.GetAndIncludeAsync(id, relationshipName);
106103
// TODO: it would be better if we could distinguish whether or not the relationship was not found,
107104
// vs the relationship not being set on the instance of T
108105
if (entity == null)
106+
{
109107
throw new JsonApiException(404, $"Relationship {relationshipName} not found.");
108+
}
110109

111-
var relationship = _jsonApiContext.ContextGraph
112-
.GetRelationship(entity, relationshipName);
113-
110+
var resource = _mapper.Map<TResource>(entity);
111+
var relationship = _jsonApiContext.ContextGraph.GetRelationship(resource, relationshipName);
114112
return relationship;
115113
}
116114

117-
public virtual async Task<TDto> CreateAsync(TDto entity)
115+
public virtual async Task<TResource> CreateAsync(TResource resource)
118116
{
119-
var createdEntity = await _entities.CreateAsync(_mapper.Map<TEntity>(entity));
120-
return _mapper.Map<TDto>(createdEntity);
117+
var entity = _mapper.Map<TEntity>(resource);
118+
entity = await _entities.CreateAsync(entity);
119+
return _mapper.Map<TResource>(entity);
121120
}
122121

123-
public virtual async Task<TDto> UpdateAsync(TId id, TDto entity)
122+
public virtual async Task<TResource> UpdateAsync(TId id, TResource resource)
124123
{
125-
var updatedEntity = await _entities.UpdateAsync(id, _mapper.Map<TEntity>(entity));
126-
return _mapper.Map<TDto>(updatedEntity);
124+
var entity = _mapper.Map<TEntity>(resource);
125+
entity = await _entities.UpdateAsync(id, entity);
126+
return _mapper.Map<TResource>(entity);
127127
}
128128

129129
public virtual async Task UpdateRelationshipsAsync(TId id, string relationshipName, List<DocumentData> relationships)
130130
{
131-
relationshipName = _jsonApiContext.ContextGraph
132-
.GetRelationshipName<TDto>(relationshipName);
133-
134-
if (relationshipName == null)
135-
throw new JsonApiException(422, "Relationship name not specified.");
136-
137131
var entity = await _entities.GetAndIncludeAsync(id, relationshipName);
138-
139132
if (entity == null)
133+
{
140134
throw new JsonApiException(404, $"Entity with id {id} could not be found.");
135+
}
141136

142137
var relationship = _jsonApiContext.ContextGraph
143-
.GetContextEntity(typeof(TDto))
138+
.GetContextEntity(typeof(TResource))
144139
.Relationships
145-
.FirstOrDefault(r => r.InternalRelationshipName == relationshipName);
140+
.FirstOrDefault(r => r.PublicRelationshipName == relationshipName);
141+
var relationshipType = relationship.Type;
142+
143+
// update relationship type with internalname
144+
var entityProperty = typeof(TEntity).GetProperty(relationship.InternalRelationshipName);
145+
if (entityProperty == null)
146+
{
147+
throw new JsonApiException(404, $"Property {relationship.InternalRelationshipName} could not be found on entity.");
148+
}
149+
relationship.Type = relationship.IsHasMany ? entityProperty.PropertyType.GetGenericArguments()[0] : entityProperty.PropertyType;
146150

147151
var relationshipIds = relationships.Select(r => r?.Id?.ToString());
148152

149153
await _entities.UpdateRelationshipsAsync(entity, relationship, relationshipIds);
154+
155+
relationship.Type = relationshipType;
150156
}
151157

152158
public virtual async Task<bool> DeleteAsync(TId id)
@@ -171,18 +177,18 @@ protected virtual IQueryable<TEntity> ApplySortAndFilterQuery(IQueryable<TEntity
171177
return entities;
172178
}
173179

174-
protected virtual async Task<IEnumerable<TDto>> ApplyPageQueryAsync(IQueryable<TEntity> entities)
180+
protected virtual async Task<IEnumerable<TResource>> ApplyPageQueryAsync(IQueryable<TEntity> entities)
175181
{
176182
var pageManager = _jsonApiContext.PageManager;
177183
if (!pageManager.IsPaginated)
178-
return _mapper.Map<IEnumerable<TDto>>(await _entities.ToListAsync(entities));
184+
return _mapper.Map<IEnumerable<TResource>>(await _entities.ToListAsync(entities));
179185

180186
if (_logger?.IsEnabled(LogLevel.Information) == true)
181187
{
182188
_logger?.LogInformation($"Applying paging query. Fetching page {pageManager.CurrentPage} with {pageManager.PageSize} entities");
183189
}
184190

185-
return _mapper.Map<IEnumerable<TDto>>(await _entities.PageAsync(entities, pageManager.PageSize, pageManager.CurrentPage));
191+
return _mapper.Map<IEnumerable<TResource>>(await _entities.PageAsync(entities, pageManager.PageSize, pageManager.CurrentPage));
186192
}
187193

188194
protected virtual IQueryable<TEntity> IncludeRelationships(IQueryable<TEntity> entities, List<string> relationships)

0 commit comments

Comments
 (0)