Skip to content

Commit c814108

Browse files
committed
Merge pull request #30 from csantero/async-materializer
add async method signatures to IMaterializer
2 parents 3d5da4f + 33adcc3 commit c814108

File tree

5 files changed

+87
-46
lines changed

5 files changed

+87
-46
lines changed

JSONAPI.EntityFramework.Tests/EntityConverterTests.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Text;
33
using System.Collections.Generic;
44
using System.Linq;
5+
using System.Threading.Tasks;
56
using Microsoft.VisualStudio.TestTools.UnitTesting;
67
using Newtonsoft.Json;
78
using JSONAPI.Core;
@@ -121,7 +122,7 @@ public void SerializeTest()
121122

122123
[TestMethod]
123124
[DeploymentItem(@"Data\Post.json")]
124-
public void DeserializePostIntegrationTest()
125+
public async Task DeserializePostIntegrationTest()
125126
{
126127
// Arrange
127128
JsonApiFormatter formatter = new JSONAPI.Json.JsonApiFormatter();
@@ -144,8 +145,8 @@ public void DeserializePostIntegrationTest()
144145

145146
// Act
146147
Post pUpdated;
147-
pUpdated = (Post)formatter.ReadFromStreamAsync(typeof(Post), stream, (System.Net.Http.HttpContent)null, (System.Net.Http.Formatting.IFormatterLogger)null).Result;
148-
pUpdated = materializer.MaterializeUpdate<Post>(pUpdated);
148+
pUpdated = (Post)await formatter.ReadFromStreamAsync(typeof(Post), stream, (System.Net.Http.HttpContent)null, (System.Net.Http.Formatting.IFormatterLogger)null);
149+
pUpdated = await materializer.MaterializeUpdateAsync<Post>(pUpdated);
149150

150151
// Assert
151152
Assert.AreEqual(a, pUpdated.Author);
@@ -156,7 +157,7 @@ public void DeserializePostIntegrationTest()
156157
}
157158

158159
[TestMethod]
159-
public void UnderpostingTest()
160+
public async Task UnderpostingTest()
160161
{
161162
// Arrange
162163
JsonApiFormatter formatter = new JSONAPI.Json.JsonApiFormatter();
@@ -172,8 +173,8 @@ public void UnderpostingTest()
172173

173174
// Act
174175
Post pUpdated;
175-
pUpdated = (Post)formatter.ReadFromStreamAsync(typeof(Post), stream, (System.Net.Http.HttpContent)null, (System.Net.Http.Formatting.IFormatterLogger)null).Result;
176-
pUpdated = materializer.MaterializeUpdate<Post>(pUpdated);
176+
pUpdated = (Post)await formatter.ReadFromStreamAsync(typeof(Post), stream, (System.Net.Http.HttpContent)null, (System.Net.Http.Formatting.IFormatterLogger)null);
177+
pUpdated = await materializer.MaterializeUpdateAsync<Post>(pUpdated);
177178

178179
// Assert
179180
Assert.AreEqual(previousCommentsCount, pUpdated.Comments.Count, "Comments were wiped out!");

JSONAPI.EntityFramework/EntityFrameworkMaterializer.cs

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public EntityFrameworkMaterializer(DbContext context) : base()
3535
/// <param name="type"></param>
3636
/// <param name="idValues"></param>
3737
/// <returns></returns>
38-
public virtual object GetById(Type type, params Object[] idValues)
38+
public virtual Task<object> GetByIdAsync(Type type, params Object[] idValues)
3939
{
4040
//TODO: How to react if the type isn't in the context?
4141

@@ -58,20 +58,20 @@ public virtual object GetById(Type type, params Object[] idValues)
5858
i++;
5959
}
6060
}
61-
return this.context.Set(type).Find(idv2);
61+
return this.context.Set(type).FindAsync(idv2);
6262
}
6363

64-
public T GetById<T>(params Object[] idValues)
64+
public async Task<T> GetByIdAsync<T>(params Object[] idValues)
6565
{
66-
return (T)GetById(typeof(T), idValues);
66+
return (T) await GetByIdAsync(typeof(T), idValues);
6767
}
6868

69-
public T Materialize<T>(T ephemeral)
69+
public async Task<T> MaterializeAsync<T>(T ephemeral)
7070
{
71-
return (T)Materialize(typeof(T), ephemeral);
71+
return (T) await MaterializeAsync(typeof(T), ephemeral);
7272
}
7373

74-
public virtual object Materialize(Type type, object ephemeral)
74+
public virtual async Task<object> MaterializeAsync(Type type, object ephemeral)
7575
{
7676
IEnumerable<string> keyNames = GetKeyNames(type);
7777
List<Object> idValues = new List<Object>();
@@ -90,7 +90,7 @@ public virtual object Materialize(Type type, object ephemeral)
9090
object retval = null;
9191
if (!anyNull)
9292
{
93-
retval = context.Set(type).Find(idValues.ToArray());
93+
retval = await context.Set(type).FindAsync(idValues.ToArray());
9494
}
9595
if (retval == null)
9696
{
@@ -101,22 +101,56 @@ public virtual object Materialize(Type type, object ephemeral)
101101
{
102102
// For a new object, if a key is specified, we want to merge the key, at least.
103103
// For simplicity then, make the behavior equivalent to MergeMaterialize in this case.
104-
this.Merge(type, ephemeral, retval);
104+
await this.Merge(type, ephemeral, retval);
105105
}
106106
}
107107
return retval;
108108
}
109109

110+
public async Task<T> MaterializeUpdateAsync<T>(T ephemeral)
111+
{
112+
return (T) await MaterializeUpdateAsync(typeof(T), ephemeral);
113+
}
114+
115+
public async Task<object> MaterializeUpdateAsync(Type type, object ephemeral)
116+
{
117+
object material = await MaterializeAsync(type, ephemeral);
118+
await this.Merge(type, ephemeral, material);
119+
return material;
120+
}
121+
122+
#endregion
123+
124+
#region Obsolete IMaterializer contract methods
125+
126+
public T GetById<T>(params object[] keyValues)
127+
{
128+
return GetByIdAsync<T>(keyValues).Result;
129+
}
130+
131+
public object GetById(Type type, params object[] keyValues)
132+
{
133+
return GetByIdAsync(type, keyValues).Result;
134+
}
135+
136+
public T Materialize<T>(T ephemeral)
137+
{
138+
return MaterializeAsync<T>(ephemeral).Result;
139+
}
140+
141+
public object Materialize(Type type, object ephemeral)
142+
{
143+
return MaterializeAsync(type, ephemeral).Result;
144+
}
145+
110146
public T MaterializeUpdate<T>(T ephemeral)
111147
{
112-
return (T)MaterializeUpdate(typeof(T), ephemeral);
148+
return MaterializeUpdateAsync<T>(ephemeral).Result;
113149
}
114150

115151
public object MaterializeUpdate(Type type, object ephemeral)
116152
{
117-
object material = Materialize(type, ephemeral);
118-
this.Merge(type, ephemeral, material);
119-
return material;
153+
return MaterializeUpdateAsync(type, ephemeral).Result;
120154
}
121155

122156
#endregion
@@ -246,7 +280,7 @@ protected EntityKey MaterializeEntityKey(Type type, object obj)
246280
return key;
247281
}
248282

249-
private void Merge (Type type, object ephemeral, object material)
283+
private async Task Merge (Type type, object ephemeral, object material)
250284
{
251285
PropertyInfo[] props = type.GetProperties();
252286
foreach (PropertyInfo prop in props)
@@ -286,15 +320,15 @@ private void Merge (Type type, object ephemeral, object material)
286320
foreach (EntityKey key in ephemeralKeys.Except(materialKeys))
287321
{
288322
object[] idParams = key.EntityKeyValues.Select(ekv => ekv.Value).ToArray();
289-
object obj = GetById(elementType, idParams);
323+
object obj = await GetByIdAsync(elementType, idParams);
290324
mmadd.Invoke(materialMany, new object[] { obj });
291325
}
292326
// Remove from hasMany
293327
if (mmremove != null)
294328
foreach (EntityKey key in materialKeys.Except(ephemeralKeys))
295329
{
296330
object[] idParams = key.EntityKeyValues.Select(ekv => ekv.Value).ToArray();
297-
object obj = GetById(elementType, idParams);
331+
object obj = await GetByIdAsync(elementType, idParams);
298332
mmremove.Invoke(materialMany, new object[] { obj });
299333
}
300334
}
@@ -312,7 +346,7 @@ private void Merge (Type type, object ephemeral, object material)
312346
if (materialKey != ephemeralKey)
313347
{
314348
object[] idParams = ephemeralKey.EntityKeyValues.Select(ekv => ekv.Value).ToArray();
315-
prop.SetValue(material, GetById(prop.PropertyType, idParams), null);
349+
prop.SetValue(material, await GetByIdAsync(prop.PropertyType, idParams), null);
316350
}
317351
// else,
318352
}
@@ -328,6 +362,5 @@ private void Merge (Type type, object ephemeral, object material)
328362
}
329363

330364
}
331-
332365
}
333366
}

JSONAPI.EntityFramework/Http/ApiController.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ protected override IQueryable<T> QueryableFactory(Core.IMaterializer materialize
3737
return ((EntityFrameworkMaterializer)materializer).DbContext.Set<T>();
3838
}
3939

40-
public override IList<T> Post(IList<T> postedObjs)
40+
public override async Task<IList<T>> Post(IList<T> postedObjs)
4141
{
4242
var materializer = this.MaterializerFactory<EntityFrameworkMaterializer>();
4343
List<T> materialList = new List<T>();
4444
foreach (T postedObj in postedObjs)
4545
{
4646
DbContext context = materializer.DbContext;
47-
var material = materializer.MaterializeUpdate(postedObj);
47+
var material = await materializer.MaterializeUpdateAsync(postedObj);
4848
if (context.Entry<T>(material).State == EntityState.Added)
4949
{
5050
context.SaveChanges();
@@ -61,28 +61,28 @@ public override IList<T> Post(IList<T> postedObjs)
6161
return materialList;
6262
}
6363

64-
public override IList<T> Put(string id, IList<T> putObjs)
64+
public override async Task<IList<T>> Put(string id, IList<T> putObjs)
6565
{
6666
var materializer = this.MaterializerFactory<EntityFrameworkMaterializer>();
6767
DbContext context = materializer.DbContext;
6868
List<T> materialList = new List<T>();
6969
foreach (T putObj in putObjs)
7070
{
71-
var material = materializer.MaterializeUpdate(putObj);
71+
var material = await materializer.MaterializeUpdateAsync(putObj);
7272
materialList.Add(material);
7373
}
7474
context.SaveChanges();
7575
return materialList;
7676
}
7777

78-
public override void Delete(string id)
78+
public override async Task Delete(string id)
7979
{
8080
var materializer = this.MaterializerFactory<EntityFrameworkMaterializer>();
8181
DbContext context = materializer.DbContext;
82-
T target = materializer.GetById<T>(id);
82+
T target = await materializer.GetByIdAsync<T>(id);
8383
context.Set<T>().Remove(target);
8484
context.SaveChanges();
85-
base.Delete(id);
85+
await base.Delete(id);
8686
}
8787

8888
protected override void Dispose(bool disposing)

JSONAPI/Core/IMaterializer.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ namespace JSONAPI.Core
88
{
99
public interface IMaterializer
1010
{
11+
Task<T> GetByIdAsync<T>(params Object[] keyValues);
12+
Task<object> GetByIdAsync(Type type, params Object[] keyValues);
13+
Task<T> MaterializeAsync<T>(T ephemeral);
14+
Task<object> MaterializeAsync(Type type, object ephemeral);
15+
Task<T> MaterializeUpdateAsync<T>(T ephemeral);
16+
Task<object> MaterializeUpdateAsync(Type type, object ephemeral);
1117

12-
T GetById<T>(params Object[] keyValues);
13-
object GetById(Type type, params Object[] keyValues);
14-
T Materialize<T>(T ephemeral);
15-
object Materialize(Type type, object ephemeral);
16-
T MaterializeUpdate<T>(T ephemeral);
17-
object MaterializeUpdate(Type type, object ephemeral);
18+
[Obsolete]T GetById<T>(params Object[] keyValues);
19+
[Obsolete]object GetById(Type type, params Object[] keyValues);
20+
[Obsolete]T Materialize<T>(T ephemeral);
21+
[Obsolete]object Materialize(Type type, object ephemeral);
22+
[Obsolete]T MaterializeUpdate<T>(T ephemeral);
23+
[Obsolete]object MaterializeUpdate(Type type, object ephemeral);
1824
}
1925
}

JSONAPI/Http/ApiController.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Text;
55
using System.Net;
66
using System.Net.Http;
7+
using System.Threading.Tasks;
78
using System.Web.Http;
89
using System.Reflection;
910
using JSONAPI.Core;
@@ -51,7 +52,7 @@ public virtual IQueryable<T> Get()
5152
return es;
5253
}
5354

54-
public virtual IEnumerable<T> Get(string id)
55+
public virtual async Task<IEnumerable<T>> Get(string id)
5556
{
5657
IMaterializer materializer = MaterializerFactory();
5758

@@ -67,7 +68,7 @@ public virtual IEnumerable<T> Get(string id)
6768
}
6869
foreach (string singleid in arrIds)
6970
{
70-
T hit = materializer.GetById<T>(singleid);
71+
T hit = await materializer.GetByIdAsync<T>(singleid);
7172
if (hit != null)
7273
{
7374
results.Add(hit);
@@ -85,29 +86,29 @@ public virtual IEnumerable<T> Get(string id)
8586
/// </summary>
8687
/// <param name="postedObj"></param>
8788
/// <returns></returns>
88-
public virtual IList<T> Post([FromBody] IList<T> postedObjs)
89+
public virtual Task<IList<T>> Post([FromBody] IList<T> postedObjs)
8990
{
9091
foreach(T postedObj in postedObjs)
9192
{
9293
IMaterializer materializer = this.MaterializerFactory();
9394
}
94-
return postedObjs;
95+
return Task.FromResult(postedObjs);
9596
}
9697

9798
/// <summary>
98-
/// Similar to Post, this method doesn't do much. It calls MaterializeUpdate() on the
99+
/// Similar to Post, this method doesn't do much. It calls MaterializeUpdateAsync() on the
99100
/// input and returns it. It should probably always be overridden.
100101
/// </summary>
101102
/// <param name="id"></param>
102103
/// <param name="payload"></param>
103104
/// <returns></returns>
104-
public virtual IList<T> Put(string id, IList<T> putObjs)
105+
public virtual async Task<IList<T>> Put(string id, IList<T> putObjs)
105106
{
106107
IMaterializer materializer = this.MaterializerFactory();
107108
IList<T> materialList = new List<T>();
108109
foreach (T putObj in putObjs)
109110
{
110-
materialList.Add(materializer.MaterializeUpdate<T>(putObj));
111+
materialList.Add(await materializer.MaterializeUpdateAsync<T>(putObj));
111112
}
112113
return materialList;
113114
}
@@ -116,9 +117,9 @@ public virtual IList<T> Put(string id, IList<T> putObjs)
116117
/// A no-op method. This should be overriden in subclasses if Delete is to be supported.
117118
/// </summary>
118119
/// <param name="id"></param>
119-
public virtual void Delete(string id)
120+
public virtual Task Delete(string id)
120121
{
121-
return;
122+
return Task.FromResult(0);
122123
}
123124
}
124125
}

0 commit comments

Comments
 (0)