Skip to content

Commit 2b64e03

Browse files
Bart Koelmanmaurei
Bart Koelman
authored andcommitted
Attr property info (#662)
* Removed AttrAttribute.InternalAttributeName * Removed unused IRelationshipField
1 parent 585bf84 commit 2b64e03

File tree

11 files changed

+32
-64
lines changed

11 files changed

+32
-64
lines changed

benchmarks/Query/QueryParser_Benchmarks.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public QueryParser_Benchmarks() {
2525
var requestMock = new Mock<IRequestContext>();
2626
requestMock.Setup(m => m.GetRequestResource()).Returns(new ResourceContext {
2727
Attributes = new List<AttrAttribute> {
28-
new AttrAttribute(ATTRIBUTE, ATTRIBUTE)
28+
new AttrAttribute(ATTRIBUTE)
2929
}
3030
});
3131
var options = new JsonApiOptions();

src/JsonApiDotNetCore/Builders/ResourceGraphBuilder.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ protected virtual List<AttrAttribute> GetAttributes(Type entityType)
9999
var idAttr = new AttrAttribute()
100100
{
101101
PublicAttributeName = _formatter.FormatPropertyName(prop),
102-
PropertyInfo = prop,
103-
InternalAttributeName = prop.Name
102+
PropertyInfo = prop
104103
};
105104
attributes.Add(idAttr);
106105
continue;
@@ -111,7 +110,6 @@ protected virtual List<AttrAttribute> GetAttributes(Type entityType)
111110
continue;
112111

113112
attribute.PublicAttributeName = attribute.PublicAttributeName ?? _formatter.FormatPropertyName(prop);
114-
attribute.InternalAttributeName = prop.Name;
115113
attribute.PropertyInfo = prop;
116114

117115
attributes.Add(attribute);

src/JsonApiDotNetCore/Extensions/IQueryableExtensions.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public static IQueryable<TSource> Filter<TSource>(this IQueryable<TSource> sourc
6565
}
6666

6767
public static IQueryable<TSource> Select<TSource>(this IQueryable<TSource> source, IEnumerable<AttrAttribute> columns)
68-
=> CallGenericSelectMethod(source, columns.Select(attr => attr.InternalAttributeName).ToList());
68+
=> CallGenericSelectMethod(source, columns.Select(attr => attr.PropertyInfo.Name).ToList());
6969

7070
public static IOrderedQueryable<TSource> Sort<TSource>(this IQueryable<TSource> source, SortQueryContext sortQuery)
7171
{
@@ -191,7 +191,7 @@ private static Expression GetFilterExpressionLambda(Expression left, Expression
191191
private static IQueryable<TSource> CallGenericWhereContainsMethod<TSource>(IQueryable<TSource> source, FilterQueryContext filter)
192192
{
193193
var concreteType = typeof(TSource);
194-
var property = concreteType.GetProperty(filter.Attribute.InternalAttributeName);
194+
var property = concreteType.GetProperty(filter.Attribute.PropertyInfo.Name);
195195

196196
try
197197
{
@@ -201,10 +201,10 @@ private static IQueryable<TSource> CallGenericWhereContainsMethod<TSource>(IQuer
201201
if (filter.IsAttributeOfRelationship)
202202
{
203203
var relation = Expression.PropertyOrField(entity, filter.Relationship.InternalRelationshipName);
204-
member = Expression.Property(relation, filter.Attribute.InternalAttributeName);
204+
member = Expression.Property(relation, filter.Attribute.PropertyInfo.Name);
205205
}
206206
else
207-
member = Expression.Property(entity, filter.Attribute.InternalAttributeName);
207+
member = Expression.Property(entity, filter.Attribute.PropertyInfo.Name);
208208

209209
var method = ContainsMethod.MakeGenericMethod(member.Type);
210210
var obj = TypeHelper.ConvertListType(propertyValues, member.Type);
@@ -259,9 +259,9 @@ private static IQueryable<TSource> CallGenericWhereMethod<TSource>(IQueryable<TS
259259
throw new ArgumentException($"'{filter.Relationship.InternalRelationshipName}' is not a valid relationship of '{concreteType}'");
260260

261261
var relatedType = filter.Relationship.RightType;
262-
property = relatedType.GetProperty(filter.Attribute.InternalAttributeName);
262+
property = relatedType.GetProperty(filter.Attribute.PropertyInfo.Name);
263263
if (property == null)
264-
throw new ArgumentException($"'{filter.Attribute.InternalAttributeName}' is not a valid attribute of '{filter.Relationship.InternalRelationshipName}'");
264+
throw new ArgumentException($"'{filter.Attribute.PropertyInfo.Name}' is not a valid attribute of '{filter.Relationship.InternalRelationshipName}'");
265265

266266
var leftRelationship = Expression.PropertyOrField(parameter, filter.Relationship.InternalRelationshipName);
267267
// {model.Relationship}
@@ -270,9 +270,9 @@ private static IQueryable<TSource> CallGenericWhereMethod<TSource>(IQueryable<TS
270270
// Is standalone attribute
271271
else
272272
{
273-
property = concreteType.GetProperty(filter.Attribute.InternalAttributeName);
273+
property = concreteType.GetProperty(filter.Attribute.PropertyInfo.Name);
274274
if (property == null)
275-
throw new ArgumentException($"'{filter.Attribute.InternalAttributeName}' is not a valid property of '{concreteType}'");
275+
throw new ArgumentException($"'{filter.Attribute.PropertyInfo.Name}' is not a valid property of '{concreteType}'");
276276

277277
// {model.Id}
278278
left = Expression.PropertyOrField(parameter, property.Name);

src/JsonApiDotNetCore/Internal/Query/BaseQueryContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ protected BaseQueryContext(TQuery query)
2323
public string GetPropertyPath()
2424
{
2525
if (IsAttributeOfRelationship)
26-
return string.Format("{0}.{1}", Relationship.InternalRelationshipName, Attribute.InternalAttributeName);
26+
return string.Format("{0}.{1}", Relationship.InternalRelationshipName, Attribute.PropertyInfo.Name);
2727

28-
return Attribute.InternalAttributeName;
28+
return Attribute.PropertyInfo.Name;
2929
}
3030
}
3131
}

src/JsonApiDotNetCore/Models/Annotation/AttrAttribute.cs

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,33 +34,12 @@ public AttrAttribute(string publicName = null, bool isImmutable = false, bool is
3434
IsSortable = isSortable;
3535
}
3636

37-
public string ExposedInternalMemberName => InternalAttributeName;
38-
39-
40-
/// <summary>
41-
/// Do not use this overload in your applications.
42-
/// Provides a method for instantiating instances of `AttrAttribute` and specifying
43-
/// the internal property name.
44-
/// The primary intent for this was to enable certain types of unit tests to be possible.
45-
/// This overload will be deprecated and removed in future releases and an alternative
46-
/// for unit tests will be provided.
47-
/// </summary>
48-
public AttrAttribute(string publicName, string internalName, bool isImmutable = false)
49-
{
50-
PublicAttributeName = publicName;
51-
InternalAttributeName = internalName;
52-
IsImmutable = isImmutable;
53-
}
37+
public string ExposedInternalMemberName => PropertyInfo.Name;
5438

5539
/// <summary>
5640
/// How this attribute is exposed through the API
5741
/// </summary>
58-
public string PublicAttributeName { get; internal set;}
59-
60-
/// <summary>
61-
/// The internal property name this attribute belongs to.
62-
/// </summary>
63-
public string InternalAttributeName { get; internal set; }
42+
public string PublicAttributeName { get; internal set; }
6443

6544
/// <summary>
6645
/// Prevents PATCH requests from updating the value.
@@ -84,7 +63,7 @@ public AttrAttribute(string publicName, string internalName, bool isImmutable =
8463
/// <summary>
8564
/// The member property info
8665
/// </summary>
87-
internal PropertyInfo PropertyInfo { get; set; }
66+
public PropertyInfo PropertyInfo { get; set; }
8867

8968
/// <summary>
9069
/// Get the value of the attribute for the given object.
@@ -119,15 +98,15 @@ public void SetValue(object entity, object newValue)
11998
private PropertyInfo GetResourceProperty(object resource)
12099
{
121100
// There are some scenarios, especially ones where users are using a different
122-
// data model than view model, where they may use a repository implmentation
101+
// data model than view model, where they may use a repository implementation
123102
// that does not match the deserialized type. For now, we will continue to support
124103
// this use case.
125104
var targetType = resource.GetType();
126105
if (targetType != PropertyInfo.DeclaringType)
127106
{
128107
var propertyInfo = resource
129108
.GetType()
130-
.GetProperty(InternalAttributeName);
109+
.GetProperty(PropertyInfo.Name);
131110

132111
return propertyInfo;
133112

src/JsonApiDotNetCore/Models/Annotation/IRelationshipField.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/JsonApiDotNetCore/Models/Annotation/RelationshipAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace JsonApiDotNetCore.Models
77
{
8-
public abstract class RelationshipAttribute : Attribute, IResourceField, IRelationshipField
8+
public abstract class RelationshipAttribute : Attribute, IResourceField
99
{
1010
protected RelationshipAttribute(string publicName, Link relationshipLinks, bool canInclude, string mappedBy)
1111
{

src/JsonApiDotNetCore/Serialization/Common/ResourceObjectBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.Linq;
@@ -31,7 +31,7 @@ public ResourceObject Build(IIdentifiable entity, IEnumerable<AttrAttribute> att
3131
var ro = new ResourceObject { Type = resourceContext.ResourceName, Id = entity.StringId.NullIfEmpty() };
3232

3333
// populating the top-level "attribute" member of a resource object. never include "id" as an attribute
34-
if (attributes != null && (attributes = attributes.Where(attr => attr.InternalAttributeName != _identifiablePropertyName)).Any())
34+
if (attributes != null && (attributes = attributes.Where(attr => attr.PropertyInfo.Name != _identifiablePropertyName)).Any())
3535
ProcessAttributes(entity, attributes, ro);
3636

3737
// populating the top-level "relationship" member of a resource object.
@@ -145,4 +145,4 @@ private void ProcessAttributes(IIdentifiable entity, IEnumerable<AttrAttribute>
145145
}
146146
}
147147
}
148-
}
148+
}

test/IntegrationTests/Data/EntityRepositoryTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public async Task UpdateAsync_AttributesUpdated_ShouldHaveSpecificallyThoseAttri
3333
arrangeContext.Add(todoItemUpdates);
3434
arrangeContext.SaveChanges();
3535

36-
var descAttr = new AttrAttribute("description", "Description")
36+
var descAttr = new AttrAttribute("description")
3737
{
3838
PropertyInfo = typeof(TodoItem).GetProperty(nameof(TodoItem.Description))
3939
};

test/UnitTests/Models/ResourceDefinitionTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void Request_Filter_Uses_Member_Expression()
2929
var attrs = resource.GetAllowedAttributes();
3030

3131
// Assert
32-
Assert.DoesNotContain(attrs, a => a.InternalAttributeName == nameof(Model.AlwaysExcluded));
32+
Assert.DoesNotContain(attrs, a => a.PropertyInfo.Name == nameof(Model.AlwaysExcluded));
3333
}
3434

3535
[Fact]
@@ -42,8 +42,8 @@ public void Request_Filter_Uses_NewExpression()
4242
var attrs = resource.GetAllowedAttributes();
4343

4444
// Assert
45-
Assert.DoesNotContain(attrs, a => a.InternalAttributeName == nameof(Model.AlwaysExcluded));
46-
Assert.DoesNotContain(attrs, a => a.InternalAttributeName == nameof(Model.Password));
45+
Assert.DoesNotContain(attrs, a => a.PropertyInfo.Name == nameof(Model.AlwaysExcluded));
46+
Assert.DoesNotContain(attrs, a => a.PropertyInfo.Name == nameof(Model.Password));
4747
}
4848
}
4949

test/UnitTests/QueryParameters/SparseFieldsServiceTests.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,10 @@ public void Parse_ValidSelection_CanParse()
3434
// Arrange
3535
const string type = "articles";
3636
const string attrName = "someField";
37-
const string internalAttrName = "SomeField";
38-
var attribute = new AttrAttribute(attrName) { InternalAttributeName = internalAttrName };
39-
var idAttribute = new AttrAttribute("id") { InternalAttributeName = "Id" };
37+
var attribute = new AttrAttribute(attrName);
38+
var idAttribute = new AttrAttribute("id");
4039

41-
var query = new KeyValuePair<string, StringValues>($"fields", new StringValues(attrName));
40+
var query = new KeyValuePair<string, StringValues>("fields", new StringValues(attrName));
4241

4342
var resourceContext = new ResourceContext
4443
{
@@ -64,9 +63,8 @@ public void Parse_TypeNameAsNavigation_Throws400ErrorWithRelationshipsOnlyMessag
6463
// Arrange
6564
const string type = "articles";
6665
const string attrName = "someField";
67-
const string internalAttrName = "SomeField";
68-
var attribute = new AttrAttribute(attrName) { InternalAttributeName = internalAttrName };
69-
var idAttribute = new AttrAttribute("id") { InternalAttributeName = "Id" };
66+
var attribute = new AttrAttribute(attrName);
67+
var idAttribute = new AttrAttribute("id");
7068

7169
var query = new KeyValuePair<string, StringValues>($"fields[{type}]", new StringValues(attrName));
7270

@@ -90,9 +88,8 @@ public void Parse_DeeplyNestedSelection_Throws400ErrorWithDeeplyNestedMessage()
9088
const string type = "articles";
9189
const string relationship = "author.employer";
9290
const string attrName = "someField";
93-
const string internalAttrName = "SomeField";
94-
var attribute = new AttrAttribute(attrName) { InternalAttributeName = internalAttrName };
95-
var idAttribute = new AttrAttribute("id") { InternalAttributeName = "Id" };
91+
var attribute = new AttrAttribute(attrName);
92+
var idAttribute = new AttrAttribute("id");
9693

9794
var query = new KeyValuePair<string, StringValues>($"fields[{relationship}]", new StringValues(attrName));
9895

0 commit comments

Comments
 (0)