Skip to content

Commit b5a7813

Browse files
committed
Closes #22 and begins to address #23.
1 parent cfcfa46 commit b5a7813

File tree

5 files changed

+108
-3
lines changed

5 files changed

+108
-3
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using JSONAPI.Core;
4+
using JSONAPI.Tests.Models;
5+
using System.Reflection;
6+
7+
namespace JSONAPI.Tests.Core
8+
{
9+
[TestClass]
10+
public class ModelManagerTests
11+
{
12+
private class InvalidModel
13+
{
14+
public string Data { get; set; }
15+
}
16+
17+
[TestMethod]
18+
public void FindsIdNamedId()
19+
{
20+
// Arrange
21+
// Act
22+
PropertyInfo idprop = ModelManager.Instance.GetIdProperty(typeof(Author));
23+
24+
// Assert
25+
Assert.AreSame(typeof(Author).GetProperty("Id"), idprop);
26+
}
27+
28+
[TestMethod]
29+
[ExpectedException(typeof(InvalidOperationException))]
30+
public void DoesntFindMissingId()
31+
{
32+
// Arrange
33+
// Act
34+
PropertyInfo idprop = ModelManager.Instance.GetIdProperty(typeof(InvalidModel));
35+
36+
// Assert
37+
Assert.Fail("An InvalidOperationException should be thrown and we shouldn't get here!");
38+
}
39+
}
40+
}

JSONAPI.Tests/JSONAPI.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<ItemGroup>
7878
<Compile Include="ActionFilters\EnableFilteringAttributeTests.cs" />
7979
<Compile Include="Core\MetadataManagerTests.cs" />
80+
<Compile Include="Core\ModelManagerTests.cs" />
8081
<Compile Include="Json\ErrorSerializerTests.cs" />
8182
<Compile Include="Json\JsonApiMediaFormaterTests.cs" />
8283
<Compile Include="Json\JsonHelpers.cs" />

JSONAPI/Core/ModelManager.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace JSONAPI.Core
9+
{
10+
class ModelManager
11+
{
12+
#region Singleton pattern
13+
14+
private static readonly ModelManager instance = new ModelManager();
15+
16+
private ModelManager() { }
17+
18+
public static ModelManager Instance
19+
{
20+
get
21+
{
22+
return instance;
23+
}
24+
}
25+
26+
#endregion
27+
28+
#region Cache storage
29+
30+
private Lazy<Dictionary<Type, PropertyInfo>> _idProperties
31+
= new Lazy<Dictionary<Type,PropertyInfo>>(
32+
() => new Dictionary<Type, PropertyInfo>()
33+
);
34+
35+
#endregion
36+
37+
#region Id property determination
38+
39+
public PropertyInfo GetIdProperty(Type type)
40+
{
41+
PropertyInfo idprop = null;
42+
43+
var idPropCache = _idProperties.Value;
44+
45+
if (idPropCache.TryGetValue(type, out idprop)) return idprop;
46+
47+
//TODO: Enable attribute-based determination
48+
49+
idprop = type.GetProperty("Id");
50+
51+
if (idprop == null)
52+
throw new InvalidOperationException(String.Format("Unable to determine Id property for type {0}", type));
53+
54+
_idProperties.Value.Add(type, idprop);
55+
56+
return idprop;
57+
}
58+
59+
#endregion
60+
}
61+
}

JSONAPI/JSONAPI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
<Compile Include="Core\IPluralizationService.cs" />
7272
<Compile Include="Core\IMaterializer.cs" />
7373
<Compile Include="Core\MetadataManager.cs" />
74+
<Compile Include="Core\ModelManager.cs" />
7475
<Compile Include="Http\ApiController.cs" />
7576
<Compile Include="Json\ErrorSerializer.cs" />
7677
<Compile Include="Json\GuidErrorIdProvider.cs" />

JSONAPI/Json/JsonApiFormatter.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ protected void Serialize(object value, Stream writeStream, JsonWriter writer, Js
152152

153153
// Do the Id now...
154154
writer.WritePropertyName("id");
155-
var idProp = GetIdProperty(value.GetType());
155+
var idProp = ModelManager.Instance.GetIdProperty(value.GetType());
156156
writer.WriteValue(GetValueForIdProperty(idProp, value));
157157

158158
PropertyInfo[] props = value.GetType().GetProperties();
@@ -819,15 +819,17 @@ protected object GetById(Type type, string id)
819819
{
820820
// Only good for creating dummy relationship objects...
821821
object retval = Activator.CreateInstance(type);
822-
PropertyInfo idprop = GetIdProperty(type);
822+
PropertyInfo idprop = ModelManager.Instance.GetIdProperty(type);
823823
idprop.SetValue(retval, System.Convert.ChangeType(id, idprop.PropertyType));
824824
return retval;
825825
}
826826

827+
/*
827828
protected PropertyInfo GetIdProperty(Type type)
828829
{
829830
return type.GetProperty("Id");
830831
}
832+
*/
831833

832834
protected string GetValueForIdProperty(PropertyInfo idprop, object obj)
833835
{
@@ -846,7 +848,7 @@ protected string GetValueForIdProperty(PropertyInfo idprop, object obj)
846848
protected string GetIdFor(object obj)
847849
{
848850
Type type = obj.GetType();
849-
PropertyInfo idprop = GetIdProperty(type);
851+
PropertyInfo idprop = ModelManager.Instance.GetIdProperty(type);
850852
return GetValueForIdProperty(idprop, obj);
851853
}
852854

0 commit comments

Comments
 (0)