Skip to content

Commit deb57df

Browse files
committed
feat(services): complete interface segregation
1 parent 3de6d21 commit deb57df

12 files changed

+190
-36
lines changed

src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,49 +12,83 @@ public class BaseJsonApiController<T, TId>
1212
: JsonApiControllerMixin
1313
where T : class, IIdentifiable<TId>
1414
{
15-
private readonly IResourceQueryService<T, TId> _queryService;
16-
private readonly IResourceCmdService<T, TId> _cmdService;
15+
private readonly IGetAllService<T, TId> _getAll;
16+
private readonly IGetByIdService<T, TId> _getById;
17+
private readonly IGetRelationshipService<T, TId> _getRelationship;
18+
private readonly IGetRelationshipsService<T, TId> _getRelationships;
19+
private readonly ICreateService<T, TId> _create;
20+
private readonly IUpdateService<T, TId> _update;
21+
private readonly IUpdateRelationshipService<T, TId> _updateRelationships;
22+
private readonly IDeleteService<T, TId> _delete;
1723
private readonly IJsonApiContext _jsonApiContext;
1824

1925
protected BaseJsonApiController(
2026
IJsonApiContext jsonApiContext,
2127
IResourceService<T, TId> resourceService)
2228
{
2329
_jsonApiContext = jsonApiContext.ApplyContext<T>();
24-
_queryService = resourceService;
25-
_cmdService = resourceService;
30+
_getAll = resourceService;
31+
_getById = resourceService;
32+
_getRelationship = resourceService;
33+
_getRelationships = resourceService;
34+
_create = resourceService;
35+
_update = resourceService;
36+
_updateRelationships = resourceService;
37+
_delete = resourceService;
2638
}
2739

2840
protected BaseJsonApiController(
2941
IJsonApiContext jsonApiContext,
30-
IResourceQueryService<T, TId> queryService)
42+
IResourceQueryService<T, TId> queryService = null,
43+
IResourceCmdService<T, TId> cmdService = null)
3144
{
3245
_jsonApiContext = jsonApiContext.ApplyContext<T>();
33-
_queryService = queryService;
46+
_getAll = queryService;
47+
_getById = queryService;
48+
_getRelationship = queryService;
49+
_getRelationships = queryService;
50+
_create = cmdService;
51+
_update = cmdService;
52+
_updateRelationships = cmdService;
53+
_delete = cmdService;
3454
}
3555

3656
protected BaseJsonApiController(
3757
IJsonApiContext jsonApiContext,
38-
IResourceCmdService<T, TId> cmdService)
58+
IGetAllService<T, TId> getAll = null,
59+
IGetByIdService<T, TId> getById = null,
60+
IGetRelationshipService<T, TId> getRelationship = null,
61+
IGetRelationshipsService<T, TId> getRelationships = null,
62+
ICreateService<T, TId> create = null,
63+
IUpdateService<T, TId> update = null,
64+
IUpdateRelationshipService<T, TId> updateRelationships = null,
65+
IDeleteService<T, TId> delete = null)
3966
{
4067
_jsonApiContext = jsonApiContext.ApplyContext<T>();
41-
_cmdService = cmdService;
68+
_getAll = getAll;
69+
_getById = getById;
70+
_getRelationship = getRelationship;
71+
_getRelationships = getRelationships;
72+
_create = create;
73+
_update = update;
74+
_updateRelationships = updateRelationships;
75+
_delete = delete;
4276
}
4377

4478
public virtual async Task<IActionResult> GetAsync()
4579
{
46-
if (_queryService == null) throw new JsonApiException(405, "Query requests are not supported");
80+
if (_getAll == null) throw new JsonApiException(405, "Query requests are not supported");
4781

48-
var entities = await _queryService.GetAsync();
82+
var entities = await _getAll.GetAsync();
4983

5084
return Ok(entities);
5185
}
5286

5387
public virtual async Task<IActionResult> GetAsync(TId id)
5488
{
55-
if (_queryService == null) throw new JsonApiException(405, "Query requests are not supported");
89+
if (_getById == null) throw new JsonApiException(405, "Query requests are not supported");
5690

57-
var entity = await _queryService.GetAsync(id);
91+
var entity = await _getById.GetAsync(id);
5892

5993
if (entity == null)
6094
return NotFound();
@@ -64,9 +98,9 @@ public virtual async Task<IActionResult> GetAsync(TId id)
6498

6599
public virtual async Task<IActionResult> GetRelationshipsAsync(TId id, string relationshipName)
66100
{
67-
if (_queryService == null) throw new JsonApiException(405, "Query requests are not supported");
101+
if (_getRelationships == null) throw new JsonApiException(405, "Query requests are not supported");
68102

69-
var relationship = await _queryService.GetRelationshipsAsync(id, relationshipName);
103+
var relationship = await _getRelationships.GetRelationshipsAsync(id, relationshipName);
70104
if (relationship == null)
71105
return NotFound();
72106

@@ -75,36 +109,36 @@ public virtual async Task<IActionResult> GetRelationshipsAsync(TId id, string re
75109

76110
public virtual async Task<IActionResult> GetRelationshipAsync(TId id, string relationshipName)
77111
{
78-
if (_queryService == null) throw new JsonApiException(405, "Query requests are not supported");
112+
if (_getRelationship == null) throw new JsonApiException(405, "Query requests are not supported");
79113

80-
var relationship = await _queryService.GetRelationshipAsync(id, relationshipName);
114+
var relationship = await _getRelationship.GetRelationshipAsync(id, relationshipName);
81115

82116
return Ok(relationship);
83117
}
84118

85119
public virtual async Task<IActionResult> PostAsync([FromBody] T entity)
86120
{
87-
if (_cmdService == null) throw new JsonApiException(405, "Command requests are not supported");
121+
if (_create == null) throw new JsonApiException(405, "Command requests are not supported");
88122

89123
if (entity == null)
90124
return UnprocessableEntity();
91125

92126
if (!_jsonApiContext.Options.AllowClientGeneratedIds && !string.IsNullOrEmpty(entity.StringId))
93127
return Forbidden();
94128

95-
entity = await _cmdService.CreateAsync(entity);
129+
entity = await _create.CreateAsync(entity);
96130

97131
return Created($"{HttpContext.Request.Path}/{entity.Id}", entity);
98132
}
99133

100134
public virtual async Task<IActionResult> PatchAsync(TId id, [FromBody] T entity)
101135
{
102-
if (_cmdService == null) throw new JsonApiException(405, "Command requests are not supported");
136+
if (_update == null) throw new JsonApiException(405, "Command requests are not supported");
103137

104138
if (entity == null)
105139
return UnprocessableEntity();
106140

107-
var updatedEntity = await _cmdService.UpdateAsync(id, entity);
141+
var updatedEntity = await _update.UpdateAsync(id, entity);
108142

109143
if (updatedEntity == null)
110144
return NotFound();
@@ -114,18 +148,18 @@ public virtual async Task<IActionResult> PatchAsync(TId id, [FromBody] T entity)
114148

115149
public virtual async Task<IActionResult> PatchRelationshipsAsync(TId id, string relationshipName, [FromBody] List<DocumentData> relationships)
116150
{
117-
if (_cmdService == null) throw new JsonApiException(405, "Command requests are not supported");
151+
if (_updateRelationships == null) throw new JsonApiException(405, "Command requests are not supported");
118152

119-
await _cmdService.UpdateRelationshipsAsync(id, relationshipName, relationships);
153+
await _updateRelationships.UpdateRelationshipsAsync(id, relationshipName, relationships);
120154

121155
return Ok();
122156
}
123157

124158
public virtual async Task<IActionResult> DeleteAsync(TId id)
125159
{
126-
if (_cmdService == null) throw new JsonApiException(405, "Command requests are not supported");
160+
if (_delete == null) throw new JsonApiException(405, "Command requests are not supported");
127161

128-
var wasDeleted = await _cmdService.DeleteAsync(id);
162+
var wasDeleted = await _delete.DeleteAsync(id);
129163

130164
if (!wasDeleted)
131165
return NotFound();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using JsonApiDotNetCore.Models;
4+
5+
namespace JsonApiDotNetCore.Services
6+
{
7+
public interface ICreateService<T> : ICreateService<T, int>
8+
where T : class, IIdentifiable<int>
9+
{ }
10+
11+
public interface ICreateService<T, in TId>
12+
where T : class, IIdentifiable<TId>
13+
{
14+
Task<T> CreateAsync(T entity);
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using JsonApiDotNetCore.Models;
4+
5+
namespace JsonApiDotNetCore.Services
6+
{
7+
public interface IDeleteService<T> : IDeleteService<T, int>
8+
where T : class, IIdentifiable<int>
9+
{ }
10+
11+
public interface IDeleteService<T, in TId>
12+
where T : class, IIdentifiable<TId>
13+
{
14+
Task<bool> DeleteAsync(TId id);
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using JsonApiDotNetCore.Models;
4+
5+
namespace JsonApiDotNetCore.Services
6+
{
7+
public interface IGetAllService<T> : IGetAllService<T, int>
8+
where T : class, IIdentifiable<int>
9+
{ }
10+
11+
public interface IGetAllService<T, in TId>
12+
where T : class, IIdentifiable<TId>
13+
{
14+
Task<IEnumerable<T>> GetAsync();
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using JsonApiDotNetCore.Models;
4+
5+
namespace JsonApiDotNetCore.Services
6+
{
7+
public interface IGetByIdService<T> : IGetByIdService<T, int>
8+
where T : class, IIdentifiable<int>
9+
{ }
10+
11+
public interface IGetByIdService<T, in TId>
12+
where T : class, IIdentifiable<TId>
13+
{
14+
Task<T> GetAsync(TId id);
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using JsonApiDotNetCore.Models;
4+
5+
namespace JsonApiDotNetCore.Services
6+
{
7+
public interface IGetRelationshipService<T> : IGetRelationshipService<T, int>
8+
where T : class, IIdentifiable<int>
9+
{ }
10+
11+
public interface IGetRelationshipService<T, in TId>
12+
where T : class, IIdentifiable<TId>
13+
{
14+
Task<object> GetRelationshipAsync(TId id, string relationshipName);
15+
}
16+
}

src/JsonApiDotNetCore/Services/IResourceQueryService.cs renamed to src/JsonApiDotNetCore/Services/Contract/IGetRelationshipsService.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@
44

55
namespace JsonApiDotNetCore.Services
66
{
7-
public interface IResourceQueryService<T> : IResourceQueryService<T, int>
7+
public interface IGetRelationshipsService<T> : IGetRelationshipsService<T, int>
88
where T : class, IIdentifiable<int>
99
{ }
1010

11-
public interface IResourceQueryService<T, in TId>
11+
public interface IGetRelationshipsService<T, in TId>
1212
where T : class, IIdentifiable<TId>
1313
{
14-
Task<IEnumerable<T>> GetAsync();
15-
Task<T> GetAsync(TId id);
1614
Task<object> GetRelationshipsAsync(TId id, string relationshipName);
17-
Task<object> GetRelationshipAsync(TId id, string relationshipName);
1815
}
1916
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using JsonApiDotNetCore.Models;
2+
3+
namespace JsonApiDotNetCore.Services
4+
{
5+
public interface IResourceCmdService<T> : IResourceCmdService<T, int>
6+
where T : class, IIdentifiable<int>
7+
{ }
8+
9+
public interface IResourceCmdService<T, in TId> :
10+
ICreateService<T, TId>,
11+
IUpdateService<T, TId>,
12+
IUpdateRelationshipService<T, TId>,
13+
IDeleteService<T, TId>
14+
where T : class, IIdentifiable<TId>
15+
{ }
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using JsonApiDotNetCore.Models;
2+
3+
namespace JsonApiDotNetCore.Services
4+
{
5+
public interface IResourceQueryService<T> : IResourceQueryService<T, int>
6+
where T : class, IIdentifiable<int>
7+
{ }
8+
9+
public interface IResourceQueryService<T, in TId> :
10+
IGetAllService<T, TId>,
11+
IGetByIdService<T, TId>,
12+
IGetRelationshipsService<T, TId>,
13+
IGetRelationshipService<T, TId>
14+
where T : class, IIdentifiable<TId>
15+
{ }
16+
}

src/JsonApiDotNetCore/Services/IResourceService.cs renamed to src/JsonApiDotNetCore/Services/Contract/IResourceService.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System.Collections.Generic;
2-
using System.Threading.Tasks;
31
using JsonApiDotNetCore.Models;
42

53
namespace JsonApiDotNetCore.Services

0 commit comments

Comments
 (0)