-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDomainEnumeration.cs
More file actions
222 lines (192 loc) · 10.1 KB
/
DomainEnumeration.cs
File metadata and controls
222 lines (192 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
using System.ComponentModel.DataAnnotations;
namespace BeyondNetCode.Shell.Ddd
{
/// <summary>
/// Represents an abstract base class for enumerations.
/// </summary>
public abstract class DomainEnumeration : IComparable
{
/// <summary>
/// Gets the name of the enumeration.
/// </summary>
[Required]
public string Name { get; private set; }
/// <summary>
/// Gets the ID of the enumeration.
/// </summary>
public int Id { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="DomainEnumeration"/> class.
/// </summary>
/// <param name="id">The ID of the enumeration.</param>
/// <param name="name">The name of the enumeration.</param>
protected DomainEnumeration(int id, string name) => (Id, Name) = (id, name);
/// <summary>
/// Returns the name of the enumeration.
/// </summary>
/// <returns>The name of the enumeration.</returns>
public override string ToString() => Name;
/// <summary>
/// Gets all the values of the specified enumeration type.
/// </summary>
/// <typeparam name="T">The enumeration type.</typeparam>
/// <returns>An enumerable collection of all the values of the specified enumeration type.</returns>
public static IEnumerable<T> GetAll<T>() where T : DomainEnumeration =>
typeof(T).GetFields(BindingFlags.Public |
BindingFlags.Static |
BindingFlags.DeclaredOnly)
.Select(f => f.GetValue(null))
.Cast<T>();
/// <summary>
/// Determines whether the current enumeration object is equal to another object.
/// </summary>
/// <param name="obj">The object to compare with the current enumeration object.</param>
/// <returns><c>true</c> if the current enumeration object is equal to the other object; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj)
{
if (obj is not DomainEnumeration otherValue)
{
return false;
}
var typeMatches = GetType().Equals(obj?.GetType());
var valueMatches = Id.Equals(otherValue.Id);
return typeMatches && valueMatches;
}
/// <summary>
/// Returns the hash code for the current enumeration object.
/// </summary>
/// <returns>The hash code for the current enumeration object.</returns>
public override int GetHashCode() => Id.GetHashCode();
/// <summary>
/// Calculates the absolute difference between two enumeration values.
/// </summary>
/// <param name="firstValue">The first enumeration value.</param>
/// <param name="secondValue">The second enumeration value.</param>
/// <returns>The absolute difference between the two enumeration values.</returns>
public static int AbsoluteDifference(DomainEnumeration firstValue, DomainEnumeration secondValue)
{
if (firstValue is null)
{
throw new ArgumentNullException(nameof(firstValue));
}
if (secondValue is null)
{
throw new ArgumentNullException(nameof(secondValue));
}
var absoluteDifference = Math.Abs(firstValue.Id - secondValue.Id);
return absoluteDifference;
}
/// <summary>
/// Retrieves the enumeration value from the specified integer value.
/// </summary>
/// <typeparam name="T">The enumeration type.</typeparam>
/// <param name="value">The integer value.</param>
/// <returns>The enumeration value that matches the specified integer value, or <c>null</c> if no match is found.</returns>
public static T? FromValue<T>(int value) where T : DomainEnumeration
{
var matchingItem = Parse<T, int>(value, "value", item => item.Id == value);
return matchingItem;
}
/// <summary>
/// Retrieves the enumeration value from the specified display name.
/// </summary>
/// <typeparam name="T">The enumeration type.</typeparam>
/// <param name="displayName">The display name.</param>
/// <returns>The enumeration value that matches the specified display name, or <c>null</c> if no match is found.</returns>
public static T? FromDisplayName<T>(string displayName) where T : DomainEnumeration
{
var matchingItem = Parse<T, string>(displayName, "display name", item => item.Name == displayName);
return matchingItem;
}
private static T? Parse<T, K>(K value, string description, Func<T, bool> predicate) where T : DomainEnumeration
{
var matchingItem = GetAll<T>().FirstOrDefault(predicate);
return matchingItem;
}
/// <summary>
/// Compares the current enumeration object with another object.
/// </summary>
/// <param name="obj">The object to compare with the current enumeration object.</param>
/// <returns>A value that indicates the relative order of the objects being compared.</returns>
#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
#pragma warning disable CA1062 // Validate arguments of public methods
public int CompareTo(object obj) => Id.CompareTo(((DomainEnumeration)obj).Id);
#pragma warning restore CA1062 // Validate arguments of public methods
#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
/// <summary>
/// Sets the value of the enumeration based on the specified integer value.
/// </summary>
/// <typeparam name="T">The enumeration type.</typeparam>
/// <param name="value">The integer value.</param>
/// <returns>The enumeration value that matches the specified integer value.</returns>
public static T? SetValue<T>(int value) where T : DomainEnumeration
{
var matchingItem = Parse<T, int>(value, "value", item => item.Id == value);
return matchingItem;
}
/// <summary>
/// Determines whether two enumeration objects are equal.
/// </summary>
/// <param name="left">The first enumeration object.</param>
/// <param name="right">The second enumeration object.</param>
/// <returns><c>true</c> if the two enumeration objects are equal; otherwise, <c>false</c>.</returns>
public static bool operator ==(DomainEnumeration left, DomainEnumeration right)
{
if (ReferenceEquals(left, null))
{
return ReferenceEquals(right, null);
}
return left.Equals(right);
}
/// <summary>
/// Determines whether two enumeration objects are not equal.
/// </summary>
/// <param name="left">The first enumeration object.</param>
/// <param name="right">The second enumeration object.</param>
/// <returns><c>true</c> if the two enumeration objects are not equal; otherwise, <c>false</c>.</returns>
public static bool operator !=(DomainEnumeration left, DomainEnumeration right)
{
return !(left == right);
}
/// <summary>
/// Determines whether the first enumeration object is less than the second enumeration object.
/// </summary>
/// <param name="left">The first enumeration object.</param>
/// <param name="right">The second enumeration object.</param>
/// <returns><c>true</c> if the first enumeration object is less than the second enumeration object; otherwise, <c>false</c>.</returns>
public static bool operator <(DomainEnumeration left, DomainEnumeration right)
{
return ReferenceEquals(left, null) ? !ReferenceEquals(right, null) : left.CompareTo(right) < 0;
}
/// <summary>
/// Determines whether the first enumeration object is less than or equal to the second enumeration object.
/// </summary>
/// <param name="left">The first enumeration object.</param>
/// <param name="right">The second enumeration object.</param>
/// <returns><c>true</c> if the first enumeration object is less than or equal to the second enumeration object; otherwise, <c>false</c>.</returns>
public static bool operator <=(DomainEnumeration left, DomainEnumeration right)
{
return ReferenceEquals(left, null) || left.CompareTo(right) <= 0;
}
/// <summary>
/// Determines whether the first enumeration object is greater than the second enumeration object.
/// </summary>
/// <param name="left">The first enumeration object.</param>
/// <param name="right">The second enumeration object.</param>
/// <returns><c>true</c> if the first enumeration object is greater than the second enumeration object; otherwise, <c>false</c>.</returns>
public static bool operator >(DomainEnumeration left, DomainEnumeration right)
{
return !ReferenceEquals(left, null) && left.CompareTo(right) > 0;
}
/// <summary>
/// Determines whether the first enumeration object is greater than or equal to the second enumeration object.
/// </summary>
/// <param name="left">The first enumeration object.</param>
/// <param name="right">The second enumeration object.</param>
/// <returns><c>true</c> if the first enumeration object is greater than or equal to the second enumeration object; otherwise, <c>false</c>.</returns>
public static bool operator >=(DomainEnumeration left, DomainEnumeration right)
{
return ReferenceEquals(left, null) ? ReferenceEquals(right, null) : left.CompareTo(right) >= 0;
}
}
}