• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / FluentCommand / 16301005024

15 Jul 2025 06:03PM UTC coverage: 54.951%. First build
16301005024

push

github

pwelter34
import data tweaks, xml doc updates

1716 of 3630 branches covered (47.27%)

Branch coverage included in aggregate %.

78 of 143 new or added lines in 11 files covered. (54.55%)

4361 of 7429 relevant lines covered (58.7%)

231.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.0
/src/FluentCommand/Reflection/MemberAccessor.cs
1
using System.ComponentModel.DataAnnotations;
2
using System.ComponentModel.DataAnnotations.Schema;
3
using System.Diagnostics;
4
using System.Reflection;
5

6
namespace FluentCommand.Reflection;
7

8
/// <summary>
9
/// Provides a base implementation for member accessors, enabling reflection-based access and metadata retrieval
10
/// for entity members (properties or fields), including support for data annotation attributes and database mapping.
11
/// </summary>
12
[DebuggerDisplay("Name: {Name}")]
13
public abstract class MemberAccessor : IMemberAccessor, IEquatable<IMemberAccessor>
14
{
15
    private readonly Lazy<ColumnAttribute> _columnAttribute;
16
    private readonly Lazy<KeyAttribute> _keyAttribute;
17
    private readonly Lazy<NotMappedAttribute> _notMappedAttribute;
18
    private readonly Lazy<DatabaseGeneratedAttribute> _databaseGeneratedAttribute;
19
    private readonly Lazy<ConcurrencyCheckAttribute> _concurrencyCheckAttribute;
20
    private readonly Lazy<ForeignKeyAttribute> _foreignKeyAttribute;
21
    private readonly Lazy<RequiredAttribute> _requiredAttribute;
22
    private readonly Lazy<DisplayAttribute> _displayAttribute;
23
    private readonly Lazy<DisplayFormatAttribute> _displayFormatAttribute;
24

25

26
    /// <summary>
27
    /// Initializes a new instance of the <see cref="MemberAccessor"/> class using the specified <see cref="MemberInfo"/>.
28
    /// </summary>
29
    /// <param name="memberInfo">The reflection metadata for the member to be accessed.</param>
30
    /// <exception cref="ArgumentNullException">Thrown if <paramref name="memberInfo"/> is <c>null</c>.</exception>
31
    protected MemberAccessor(MemberInfo memberInfo)
172✔
32
    {
33
        MemberInfo = memberInfo ?? throw new ArgumentNullException(nameof(memberInfo));
172!
34

35
        _columnAttribute = new Lazy<ColumnAttribute>(() => MemberInfo.GetCustomAttribute<ColumnAttribute>(true));
329✔
36
        _keyAttribute = new Lazy<KeyAttribute>(() => MemberInfo.GetCustomAttribute<KeyAttribute>(true));
227✔
37
        _notMappedAttribute = new Lazy<NotMappedAttribute>(() => MemberInfo.GetCustomAttribute<NotMappedAttribute>(true));
301✔
38
        _databaseGeneratedAttribute = new Lazy<DatabaseGeneratedAttribute>(() => MemberInfo.GetCustomAttribute<DatabaseGeneratedAttribute>(true));
266✔
39
        _concurrencyCheckAttribute = new Lazy<ConcurrencyCheckAttribute>(() => MemberInfo.GetCustomAttribute<ConcurrencyCheckAttribute>(true));
209✔
40
        _foreignKeyAttribute = new Lazy<ForeignKeyAttribute>(() => MemberInfo.GetCustomAttribute<ForeignKeyAttribute>(true));
172✔
41
        _requiredAttribute = new Lazy<RequiredAttribute>(() => MemberInfo.GetCustomAttribute<RequiredAttribute>(true));
190✔
42
        _displayAttribute = new Lazy<DisplayAttribute>(() => MemberInfo.GetCustomAttribute<DisplayAttribute>(true));
190✔
43
        _displayFormatAttribute = new Lazy<DisplayFormatAttribute>(() => MemberInfo.GetCustomAttribute<DisplayFormatAttribute>(true));
172✔
44
    }
172✔
45

46
    /// <summary>
47
    /// Gets the <see cref="Type"/> of the member (property or field).
48
    /// </summary>
49
    /// <value>The <see cref="Type"/> representing the member's data type.</value>
50
    public abstract Type MemberType { get; }
51

52
    /// <summary>
53
    /// Gets the <see cref="MemberInfo"/> instance for the accessor, providing reflection metadata.
54
    /// </summary>
55
    /// <value>The <see cref="MemberInfo"/> for the member.</value>
56
    public MemberInfo MemberInfo { get; }
508✔
57

58
    /// <summary>
59
    /// Gets the name of the member as defined in the entity.
60
    /// </summary>
61
    /// <value>The member's name.</value>
62
    public abstract string Name { get; }
63

64
    /// <summary>
65
    /// Gets a value indicating whether this member has a getter method.
66
    /// </summary>
67
    /// <value><c>true</c> if the member has a getter; otherwise, <c>false</c>.</value>
68
    public abstract bool HasGetter { get; }
69

70
    /// <summary>
71
    /// Gets a value indicating whether this member has a setter method.
72
    /// </summary>
73
    /// <value><c>true</c> if the member has a setter; otherwise, <c>false</c>.</value>
74
    public abstract bool HasSetter { get; }
75

76
    /// <summary>
77
    /// Gets the name of the database column that the member is mapped to.
78
    /// This value is determined by the <see cref="ColumnAttribute.Name"/> property if specified,
79
    /// otherwise it defaults to the member name.
80
    /// </summary>
81
    /// <value>The mapped database column name.</value>
82
    public string Column => _columnAttribute.Value?.Name ?? Name;
3,667✔
83

84
    /// <summary>
85
    /// Gets the database provider-specific data type of the column the member is mapped to.
86
    /// This value is determined by the <see cref="ColumnAttribute.TypeName"/> property if specified.
87
    /// </summary>
88
    /// <value>The provider-specific column data type.</value>
89
    public string ColumnType => _columnAttribute.Value?.TypeName;
131✔
90

91
    /// <summary>
92
    /// Gets the zero-based order of the column the member is mapped to in the database.
93
    /// This value is determined by the <see cref="ColumnAttribute.Order"/> property if specified.
94
    /// </summary>
95
    /// <value>The zero-based column order, or <c>null</c> if not specified.</value>
96
    public int? ColumnOrder => _columnAttribute.Value?.Order;
×
97

98
    /// <summary>
99
    /// Gets a value indicating whether this member is the primary key for the entity.
100
    /// This is determined by the presence of the <see cref="KeyAttribute"/>.
101
    /// </summary>
102
    /// <value><c>true</c> if this member is a primary key; otherwise, <c>false</c>.</value>
103
    public bool IsKey => _keyAttribute.Value != null;
281✔
104

105
    /// <summary>
106
    /// Gets a value indicating whether this member should be excluded from database mapping.
107
    /// This is determined by the presence of the <see cref="NotMappedAttribute"/>.
108
    /// </summary>
109
    /// <value><c>true</c> if this member is not mapped to a database column; otherwise, <c>false</c>.</value>
110
    public bool IsNotMapped => _notMappedAttribute.Value != null;
410✔
111

112
    /// <summary>
113
    /// Gets a value indicating whether this member participates in optimistic concurrency checks.
114
    /// This is determined by the presence of the <see cref="ConcurrencyCheckAttribute"/>.
115
    /// </summary>
116
    /// <value><c>true</c> if this member is used for concurrency checking; otherwise, <c>false</c>.</value>
117
    public bool IsConcurrencyCheck => _concurrencyCheckAttribute.Value != null;
259✔
118

119
    /// <summary>
120
    /// Gets a value indicating whether this member's value is generated by the database.
121
    /// This is determined by the presence of the <see cref="DatabaseGeneratedAttribute"/> and its option.
122
    /// </summary>
123
    /// <value><c>true</c> if the value is generated by the database; otherwise, <c>false</c>.</value>
124
    public bool IsDatabaseGenerated => _databaseGeneratedAttribute.Value != null
475✔
125
        && _databaseGeneratedAttribute.Value.DatabaseGeneratedOption != DatabaseGeneratedOption.None;
475✔
126

127
    /// <summary>
128
    /// Gets the name of the associated navigation property or foreign key(s) for this member.
129
    /// This value is determined by the <see cref="ForeignKeyAttribute.Name"/> property if specified.
130
    /// </summary>
131
    /// <value>The name of the navigation property or foreign key(s), or <c>null</c> if not applicable.</value>
NEW
132
    public string ForeignKey => _foreignKeyAttribute.Value?.Name;
×
133

134
    /// <summary>
135
    /// Gets a value indicating whether this member is required (non-nullable or marked as required).
136
    /// This is determined by the presence of the <see cref="RequiredAttribute"/>.
137
    /// </summary>
138
    /// <value><c>true</c> if the member is required; otherwise, <c>false</c>.</value>
139
    public bool IsRequired => _requiredAttribute.Value != null;
19✔
140

141
    /// <summary>
142
    /// Gets the display name of the member, typically used for UI or reporting purposes.
143
    /// This value is determined by the <see cref="DisplayAttribute.Name"/> property if specified; otherwise, the member name.
144
    /// </summary>
145
    /// <value>The display name of the member.</value>
146
    public string DisplayName => _displayAttribute.Value?.Name ?? Name;
19!
147

148
    /// <summary>
149
    /// Gets the format string used to display the member's value, if specified.
150
    /// This value is determined by the <see cref="DisplayFormatAttribute.DataFormatString"/> property if present.
151
    /// </summary>
152
    /// <value>
153
    /// The data format string for display formatting, or <c>null</c> if not specified.
154
    /// </value>
NEW
155
    public string DataFormatString => _displayFormatAttribute.Value?.DataFormatString;
×
156

157
    /// <summary>
158
    /// Returns the value of the member for the specified object instance.
159
    /// </summary>
160
    /// <param name="instance">The object whose member value will be returned.</param>
161
    /// <returns>The value of the member for the given <paramref name="instance"/>.</returns>
162
    public abstract object GetValue(object instance);
163

164
    /// <summary>
165
    /// Sets the value of the member for the specified object instance.
166
    /// </summary>
167
    /// <param name="instance">The object whose member value will be set.</param>
168
    /// <param name="value">The new value to assign to the member.</param>
169
    public abstract void SetValue(object instance, object value);
170

171

172
    /// <summary>
173
    /// Determines whether the specified <see cref="IMemberAccessor"/> is equal to this instance.
174
    /// </summary>
175
    /// <param name="other">The <see cref="IMemberAccessor"/> to compare with this instance.</param>
176
    /// <returns><c>true</c> if the specified accessor is equal to this instance; otherwise, <c>false</c>.</returns>
177
    public bool Equals(IMemberAccessor other)
178
    {
179
        if (ReferenceEquals(null, other))
×
180
            return false;
×
181
        if (ReferenceEquals(this, other))
×
182
            return true;
×
183

184
        return Equals(other.MemberInfo, MemberInfo);
×
185
    }
186

187
    /// <summary>
188
    /// Determines whether the specified <see cref="object"/> is equal to this instance.
189
    /// </summary>
190
    /// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
191
    /// <returns><c>true</c> if the specified object is equal to this instance; otherwise, <c>false</c>.</returns>
192
    public override bool Equals(object obj)
193
    {
194
        if (ReferenceEquals(null, obj))
×
195
            return false;
×
196
        if (ReferenceEquals(this, obj))
×
197
            return true;
×
198
        if (obj.GetType() != typeof(MemberAccessor))
×
199
            return false;
×
200

201
        return Equals((MemberAccessor)obj);
×
202
    }
203

204
    /// <summary>
205
    /// Returns a hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
206
    /// </summary>
207
    /// <returns>A hash code for this instance.</returns>
208
    public override int GetHashCode()
209
    {
210
        return MemberInfo.GetHashCode();
×
211
    }
212
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc