1
- using System ;
2
- using System . Collections ;
3
- using System . Collections . Generic ;
4
- using System . Linq ;
5
- using System . Reflection ;
6
- using System . Threading . Tasks ;
7
1
using AutoMapper ;
8
2
using JsonApiDotNetCore . Data ;
9
- using JsonApiDotNetCore . Extensions ;
10
3
using JsonApiDotNetCore . Internal ;
11
4
using JsonApiDotNetCore . Models ;
12
5
using Microsoft . Extensions . Logging ;
6
+ using System ;
7
+ using System . Collections . Generic ;
8
+ using System . Linq ;
9
+ using System . Threading . Tasks ;
13
10
14
11
namespace JsonApiDotNetCore . Services
15
12
{
16
- public class MappingResourceService < TResource , TEntity >
17
- : MappingResourceService < TResource , TEntity , int > ,
13
+ public class DefaultResourceService < TResource > : DefaultResourceService < TResource , int > ,
18
14
IResourceService < TResource >
19
15
where TResource : class , IIdentifiable < int >
20
- where TEntity : class , IIdentifiable < int >
21
16
{
22
- public MappingResourceService (
23
- IJsonApiContext jsonApiContext ,
24
- IEntityRepository < TEntity > entityRepository ,
25
- ILoggerFactory loggerFactory ,
26
- IMapper mapper )
27
- : base ( jsonApiContext , entityRepository , loggerFactory , mapper )
17
+ public DefaultResourceService (
18
+ IJsonApiContext jsonApiContext ,
19
+ IEntityRepository < TResource > entityRepository ,
20
+ ILoggerFactory loggerFactory ) :
21
+ base ( jsonApiContext , entityRepository , loggerFactory )
22
+ { }
23
+ }
24
+
25
+ public class DefaultResourceService < TResource , TId > : DefaultResourceService < TResource , TResource , TId > ,
26
+ IResourceService < TResource , TId >
27
+ where TResource : class , IIdentifiable < TId >
28
+ {
29
+ public DefaultResourceService (
30
+ IJsonApiContext jsonApiContext ,
31
+ IEntityRepository < TResource , TId > entityRepository ,
32
+ ILoggerFactory loggerFactory ) :
33
+ base ( jsonApiContext , entityRepository , loggerFactory )
28
34
{ }
29
35
}
30
36
31
- public class MappingResourceService < TResource , TEntity , TId >
32
- : IResourceService < TResource , TId >
37
+ public class DefaultResourceService < TResource , TEntity , TId > :
38
+ IResourceService < TResource , TId >
33
39
where TResource : class , IIdentifiable < TId >
34
40
where TEntity : class , IIdentifiable < TId >
35
41
{
@@ -38,18 +44,49 @@ public class MappingResourceService<TResource, TEntity, TId>
38
44
private readonly ILogger _logger ;
39
45
private readonly IMapper _mapper ;
40
46
41
- public MappingResourceService (
47
+ public DefaultResourceService (
48
+ IJsonApiContext jsonApiContext ,
49
+ IEntityRepository < TEntity , TId > entityRepository ,
50
+ ILoggerFactory loggerFactory )
51
+ {
52
+ // no mapper provided, TResource & TEntity must be the same type
53
+ if ( typeof ( TResource ) != typeof ( TEntity ) )
54
+ {
55
+ throw new InvalidOperationException ( "Resource and Entity types are NOT the same. " +
56
+ "Please provide a mapper." ) ;
57
+ }
58
+
59
+ _jsonApiContext = jsonApiContext ;
60
+ _entities = entityRepository ;
61
+ _logger = loggerFactory . CreateLogger < DefaultResourceService < TResource , TEntity , TId > > ( ) ;
62
+ }
63
+
64
+ public DefaultResourceService (
42
65
IJsonApiContext jsonApiContext ,
43
66
IEntityRepository < TEntity , TId > entityRepository ,
44
67
ILoggerFactory loggerFactory ,
45
68
IMapper mapper )
46
69
{
47
70
_jsonApiContext = jsonApiContext ;
48
71
_entities = entityRepository ;
49
- _logger = loggerFactory . CreateLogger < MappingResourceService < TResource , TEntity , TId > > ( ) ;
72
+ _logger = loggerFactory . CreateLogger < DefaultResourceService < TResource , TEntity , TId > > ( ) ;
50
73
_mapper = mapper ;
51
74
}
52
75
76
+ public virtual async Task < TResource > CreateAsync ( TResource resource )
77
+ {
78
+ var entity = ( typeof ( TResource ) == typeof ( TEntity ) ) ? resource as TEntity :
79
+ _mapper . Map < TEntity > ( resource ) ;
80
+ entity = await _entities . CreateAsync ( entity ) ;
81
+ return ( typeof ( TResource ) == typeof ( TEntity ) ) ? entity as TResource :
82
+ _mapper . Map < TResource > ( entity ) ;
83
+ }
84
+
85
+ public virtual async Task < bool > DeleteAsync ( TId id )
86
+ {
87
+ return await _entities . DeleteAsync ( id ) ;
88
+ }
89
+
53
90
public virtual async Task < IEnumerable < TResource > > GetAsync ( )
54
91
{
55
92
var entities = _entities . Get ( ) ;
@@ -75,25 +112,12 @@ public virtual async Task<TResource> GetAsync(TId id)
75
112
else
76
113
{
77
114
TEntity entity = await _entities . GetAsync ( id ) ;
78
- dto = _mapper . Map < TResource > ( entity ) ;
115
+ dto = ( typeof ( TResource ) == typeof ( TEntity ) ) ? entity as TResource :
116
+ _mapper . Map < TResource > ( entity ) ;
79
117
}
80
118
return dto ;
81
119
}
82
120
83
- private bool ShouldIncludeRelationships ( )
84
- => ( _jsonApiContext . QuerySet ? . IncludedRelationships != null && _jsonApiContext . QuerySet . IncludedRelationships . Count > 0 ) ;
85
-
86
- private async Task < TResource > GetWithRelationshipsAsync ( TId id )
87
- {
88
- var query = _entities . Get ( ) . Where ( e => e . Id . Equals ( id ) ) ;
89
- _jsonApiContext . QuerySet . IncludedRelationships . ForEach ( r =>
90
- {
91
- query = _entities . Include ( query , r ) ;
92
- } ) ;
93
- var value = await _entities . FirstOrDefaultAsync ( query ) ;
94
- return _mapper . Map < TResource > ( value ) ;
95
- }
96
-
97
121
public virtual async Task < object > GetRelationshipsAsync ( TId id , string relationshipName )
98
122
=> await GetRelationshipAsync ( id , relationshipName ) ;
99
123
@@ -107,26 +131,23 @@ public virtual async Task<object> GetRelationshipAsync(TId id, string relationsh
107
131
throw new JsonApiException ( 404 , $ "Relationship { relationshipName } not found.") ;
108
132
}
109
133
110
- var resource = _mapper . Map < TResource > ( entity ) ;
134
+ var resource = ( typeof ( TResource ) == typeof ( TEntity ) ) ? entity as TResource :
135
+ _mapper . Map < TResource > ( entity ) ;
111
136
var relationship = _jsonApiContext . ContextGraph . GetRelationship ( resource , relationshipName ) ;
112
137
return relationship ;
113
138
}
114
139
115
- public virtual async Task < TResource > CreateAsync ( TResource resource )
116
- {
117
- var entity = _mapper . Map < TEntity > ( resource ) ;
118
- entity = await _entities . CreateAsync ( entity ) ;
119
- return _mapper . Map < TResource > ( entity ) ;
120
- }
121
-
122
140
public virtual async Task < TResource > UpdateAsync ( TId id , TResource resource )
123
141
{
124
- var entity = _mapper . Map < TEntity > ( resource ) ;
142
+ var entity = ( typeof ( TResource ) == typeof ( TEntity ) ) ? resource as TEntity :
143
+ _mapper . Map < TEntity > ( resource ) ;
125
144
entity = await _entities . UpdateAsync ( id , entity ) ;
126
- return _mapper . Map < TResource > ( entity ) ;
145
+ return ( typeof ( TResource ) == typeof ( TEntity ) ) ? entity as TResource :
146
+ _mapper . Map < TResource > ( entity ) ;
127
147
}
128
148
129
- public virtual async Task UpdateRelationshipsAsync ( TId id , string relationshipName , List < DocumentData > relationships )
149
+ public virtual async Task UpdateRelationshipsAsync ( TId id , string relationshipName ,
150
+ List < DocumentData > relationships )
130
151
{
131
152
var entity = await _entities . GetAndIncludeAsync ( id , relationshipName ) ;
132
153
if ( entity == null )
@@ -137,16 +158,18 @@ public virtual async Task UpdateRelationshipsAsync(TId id, string relationshipNa
137
158
var relationship = _jsonApiContext . ContextGraph
138
159
. GetContextEntity ( typeof ( TResource ) )
139
160
. Relationships
140
- . FirstOrDefault ( r => r . PublicRelationshipName == relationshipName ) ;
161
+ . FirstOrDefault ( r => r . Is ( relationshipName ) ) ;
141
162
var relationshipType = relationship . Type ;
142
163
143
164
// update relationship type with internalname
144
165
var entityProperty = typeof ( TEntity ) . GetProperty ( relationship . InternalRelationshipName ) ;
145
166
if ( entityProperty == null )
146
167
{
147
- throw new JsonApiException ( 404 , $ "Property { relationship . InternalRelationshipName } could not be found on entity.") ;
168
+ throw new JsonApiException ( 404 , $ "Property { relationship . InternalRelationshipName } " +
169
+ $ "could not be found on entity.") ;
148
170
}
149
- relationship . Type = relationship . IsHasMany ? entityProperty . PropertyType . GetGenericArguments ( ) [ 0 ] : entityProperty . PropertyType ;
171
+ relationship . Type = relationship . IsHasMany ? entityProperty . PropertyType . GetGenericArguments ( ) [ 0 ] :
172
+ entityProperty . PropertyType ;
150
173
151
174
var relationshipIds = relationships . Select ( r => r ? . Id ? . ToString ( ) ) ;
152
175
@@ -155,9 +178,26 @@ public virtual async Task UpdateRelationshipsAsync(TId id, string relationshipNa
155
178
relationship . Type = relationshipType ;
156
179
}
157
180
158
- public virtual async Task < bool > DeleteAsync ( TId id )
181
+ protected virtual async Task < IEnumerable < TResource > > ApplyPageQueryAsync ( IQueryable < TEntity > entities )
159
182
{
160
- return await _entities . DeleteAsync ( id ) ;
183
+ var pageManager = _jsonApiContext . PageManager ;
184
+ if ( ! pageManager . IsPaginated )
185
+ {
186
+ var allEntities = await _entities . ToListAsync ( entities ) ;
187
+ return ( typeof ( TResource ) == typeof ( TEntity ) ) ? allEntities as IEnumerable < TResource > :
188
+ _mapper . Map < IEnumerable < TResource > > ( allEntities ) ;
189
+ }
190
+
191
+ if ( _logger ? . IsEnabled ( LogLevel . Information ) == true )
192
+ {
193
+ _logger ? . LogInformation ( $ "Applying paging query. Fetching page { pageManager . CurrentPage } " +
194
+ $ "with { pageManager . PageSize } entities") ;
195
+ }
196
+
197
+ var pagedEntities = await _entities . PageAsync ( entities , pageManager . PageSize ,
198
+ pageManager . CurrentPage ) ;
199
+ return ( typeof ( TResource ) == typeof ( TEntity ) ) ? pagedEntities as IEnumerable < TResource > :
200
+ _mapper . Map < IEnumerable < TResource > > ( pagedEntities ) ;
161
201
}
162
202
163
203
protected virtual IQueryable < TEntity > ApplySortAndFilterQuery ( IQueryable < TEntity > entities )
@@ -177,21 +217,8 @@ protected virtual IQueryable<TEntity> ApplySortAndFilterQuery(IQueryable<TEntity
177
217
return entities ;
178
218
}
179
219
180
- protected virtual async Task < IEnumerable < TResource > > ApplyPageQueryAsync ( IQueryable < TEntity > entities )
181
- {
182
- var pageManager = _jsonApiContext . PageManager ;
183
- if ( ! pageManager . IsPaginated )
184
- return _mapper . Map < IEnumerable < TResource > > ( await _entities . ToListAsync ( entities ) ) ;
185
-
186
- if ( _logger ? . IsEnabled ( LogLevel . Information ) == true )
187
- {
188
- _logger ? . LogInformation ( $ "Applying paging query. Fetching page { pageManager . CurrentPage } with { pageManager . PageSize } entities") ;
189
- }
190
-
191
- return _mapper . Map < IEnumerable < TResource > > ( await _entities . PageAsync ( entities , pageManager . PageSize , pageManager . CurrentPage ) ) ;
192
- }
193
-
194
- protected virtual IQueryable < TEntity > IncludeRelationships ( IQueryable < TEntity > entities , List < string > relationships )
220
+ protected virtual IQueryable < TEntity > IncludeRelationships ( IQueryable < TEntity > entities ,
221
+ List < string > relationships )
195
222
{
196
223
_jsonApiContext . IncludedRelationships = relationships ;
197
224
@@ -200,5 +227,21 @@ protected virtual IQueryable<TEntity> IncludeRelationships(IQueryable<TEntity> e
200
227
201
228
return entities ;
202
229
}
230
+
231
+ private async Task < TResource > GetWithRelationshipsAsync ( TId id )
232
+ {
233
+ var query = _entities . Get ( ) . Where ( e => e . Id . Equals ( id ) ) ;
234
+ _jsonApiContext . QuerySet . IncludedRelationships . ForEach ( r =>
235
+ {
236
+ query = _entities . Include ( query , r ) ;
237
+ } ) ;
238
+ var value = await _entities . FirstOrDefaultAsync ( query ) ;
239
+ return ( typeof ( TResource ) == typeof ( TEntity ) ) ? value as TResource :
240
+ _mapper . Map < TResource > ( value ) ;
241
+ }
242
+
243
+ private bool ShouldIncludeRelationships ( )
244
+ => ( _jsonApiContext . QuerySet ? . IncludedRelationships != null &&
245
+ _jsonApiContext . QuerySet . IncludedRelationships . Count > 0 ) ;
203
246
}
204
247
}
0 commit comments