@@ -18,7 +18,7 @@ namespace JSONAPI.EntityFramework.Http
1818 /// </summary>
1919 public class EntityFrameworkDocumentMaterializer < T > : IDocumentMaterializer where T : class
2020 {
21- private readonly DbContext _dbContext ;
21+ protected readonly DbContext DbContext ;
2222 private readonly IResourceTypeRegistration _resourceTypeRegistration ;
2323 private readonly IQueryableResourceCollectionDocumentBuilder _queryableResourceCollectionDocumentBuilder ;
2424 private readonly ISingleResourceDocumentBuilder _singleResourceDocumentBuilder ;
@@ -38,7 +38,7 @@ public EntityFrameworkDocumentMaterializer(
3838 ISortExpressionExtractor sortExpressionExtractor ,
3939 IBaseUrlService baseUrlService )
4040 {
41- _dbContext = dbContext ;
41+ DbContext = dbContext ;
4242 _resourceTypeRegistration = resourceTypeRegistration ;
4343 _queryableResourceCollectionDocumentBuilder = queryableResourceCollectionDocumentBuilder ;
4444 _singleResourceDocumentBuilder = singleResourceDocumentBuilder ;
@@ -49,7 +49,7 @@ public EntityFrameworkDocumentMaterializer(
4949
5050 public virtual Task < IResourceCollectionDocument > GetRecords ( HttpRequestMessage request , CancellationToken cancellationToken )
5151 {
52- var query = _dbContext . Set < T > ( ) . AsQueryable ( ) ;
52+ var query = DbContext . Set < T > ( ) . AsQueryable ( ) ;
5353 var sortExpressions = _sortExpressionExtractor . ExtractSortExpressions ( request ) ;
5454 return _queryableResourceCollectionDocumentBuilder . BuildDocument ( query , request , sortExpressions , cancellationToken ) ;
5555 }
@@ -68,29 +68,33 @@ public virtual async Task<ISingleResourceDocument> CreateRecord(ISingleResourceD
6868 HttpRequestMessage request , CancellationToken cancellationToken )
6969 {
7070 var apiBaseUrl = GetBaseUrlFromRequest ( request ) ;
71- var newRecord = await MaterializeAsync ( requestDocument . PrimaryData , cancellationToken ) ;
72- await _dbContext . SaveChangesAsync ( cancellationToken ) ;
73- var returnDocument = _singleResourceDocumentBuilder . BuildDocument ( newRecord , apiBaseUrl , null , null ) ;
71+ var newRecord = MaterializeAsync ( requestDocument . PrimaryData , cancellationToken ) ;
72+ await OnCreate ( newRecord ) ;
73+ await DbContext . SaveChangesAsync ( cancellationToken ) ;
74+ var returnDocument = _singleResourceDocumentBuilder . BuildDocument ( await newRecord , apiBaseUrl , null , null ) ;
7475
7576 return returnDocument ;
7677 }
7778
79+
7880 public virtual async Task < ISingleResourceDocument > UpdateRecord ( string id , ISingleResourceDocument requestDocument ,
7981 HttpRequestMessage request , CancellationToken cancellationToken )
8082 {
8183 var apiBaseUrl = GetBaseUrlFromRequest ( request ) ;
82- var newRecord = await MaterializeAsync ( requestDocument . PrimaryData , cancellationToken ) ;
83- var returnDocument = _singleResourceDocumentBuilder . BuildDocument ( newRecord , apiBaseUrl , null , null ) ;
84- await _dbContext . SaveChangesAsync ( cancellationToken ) ;
84+ var newRecord = MaterializeAsync ( requestDocument . PrimaryData , cancellationToken ) ;
85+ await OnUpdate ( newRecord ) ;
86+ var returnDocument = _singleResourceDocumentBuilder . BuildDocument ( await newRecord , apiBaseUrl , null , null ) ;
87+ await DbContext . SaveChangesAsync ( cancellationToken ) ;
8588
8689 return returnDocument ;
8790 }
8891
8992 public virtual async Task < IJsonApiDocument > DeleteRecord ( string id , HttpRequestMessage request , CancellationToken cancellationToken )
9093 {
91- var singleResource = await _dbContext . Set < T > ( ) . FindAsync ( cancellationToken , Convert . ChangeType ( id , _resourceTypeRegistration . IdProperty . PropertyType ) ) ;
92- _dbContext . Set < T > ( ) . Remove ( singleResource ) ;
93- await _dbContext . SaveChangesAsync ( cancellationToken ) ;
94+ var singleResource = DbContext . Set < T > ( ) . FindAsync ( cancellationToken , Convert . ChangeType ( id , _resourceTypeRegistration . IdProperty . PropertyType ) ) ;
95+ await OnDelete ( singleResource ) ;
96+ DbContext . Set < T > ( ) . Remove ( await singleResource ) ;
97+ await DbContext . SaveChangesAsync ( cancellationToken ) ;
9498
9599 return null ;
96100 }
@@ -107,9 +111,9 @@ protected string GetBaseUrlFromRequest(HttpRequestMessage request)
107111 /// Convert a resource object into a material record managed by EntityFramework.
108112 /// </summary>
109113 /// <returns></returns>
110- protected virtual async Task < object > MaterializeAsync ( IResourceObject resourceObject , CancellationToken cancellationToken )
114+ protected virtual async Task < T > MaterializeAsync ( IResourceObject resourceObject , CancellationToken cancellationToken )
111115 {
112- return await _entityFrameworkResourceObjectMaterializer . MaterializeResourceObject ( resourceObject , cancellationToken ) ;
116+ return ( T ) await _entityFrameworkResourceObjectMaterializer . MaterializeResourceObject ( resourceObject , cancellationToken ) ;
113117 }
114118
115119 /// <summary>
@@ -155,10 +159,40 @@ protected async Task<ISingleResourceDocument> GetRelatedToOne<TRelated>(string i
155159 return _singleResourceDocumentBuilder . BuildDocument ( relatedResource , GetBaseUrlFromRequest ( request ) , null , null ) ;
156160 }
157161
162+
163+ /// <summary>
164+ /// Manipulate entity before create.
165+ /// </summary>
166+ /// <param name="record"></param>
167+ /// <returns></returns>
168+ protected virtual async Task OnCreate ( Task < T > record )
169+ {
170+ await record ;
171+ }
172+
173+ /// <summary>
174+ /// Manipulate entity before update.
175+ /// </summary>
176+ /// <param name="record"></param>
177+ protected virtual async Task OnUpdate ( Task < T > record )
178+ {
179+ await record ;
180+ }
181+
182+ /// <summary>
183+ /// Manipulate entity before delete.
184+ /// </summary>
185+ /// <param name="record"></param>
186+ /// <returns></returns>
187+ protected virtual async Task OnDelete ( Task < T > record )
188+ {
189+ await record ;
190+ }
191+
158192 private IQueryable < TResource > Filter < TResource > ( Expression < Func < TResource , bool > > predicate ,
159193 params Expression < Func < TResource , object > > [ ] includes ) where TResource : class
160194 {
161- IQueryable < TResource > query = _dbContext . Set < TResource > ( ) ;
195+ IQueryable < TResource > query = DbContext . Set < TResource > ( ) ;
162196 if ( includes != null && includes . Any ( ) )
163197 query = includes . Aggregate ( query , ( current , include ) => current . Include ( include ) ) ;
164198
0 commit comments