-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathStaticTypeLookupService.cs
172 lines (156 loc) · 8.28 KB
/
StaticTypeLookupService.cs
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
/*==============================================================================================================================
| Author Ignia, LLC
| Client Ignia, LLC
| Project Topics Library
\=============================================================================================================================*/
using System.Reflection;
namespace OnTopic.Lookup {
/*============================================================================================================================
| CLASS: STATIC TYPE LOOKUP SERVICE
\---------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// The <see cref="StaticTypeLookupService"/> can be configured to provide a lookup of <see cref="Type"/> classes based on
/// its name.
/// </summary>
public class StaticTypeLookupService: ITypeLookupService {
/*==========================================================================================================================
| PRIVATE VARIABLES
\-------------------------------------------------------------------------------------------------------------------------*/
private readonly TypeCollection _typeCollection = new();
/*==========================================================================================================================
| CONSTRUCTOR
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Establishes a new instance of a <see cref="StaticTypeLookupService"/>. Optionally accepts a list of <see cref="Type"/>
/// instances and a default <see cref="Type"/> value.
/// </summary>
/// <remarks>
/// Any <see cref="Type"/> instances submitted via <paramref name="types"/> should be unique by <see
/// cref="MemberInfo.Name"/>; if they are not, they will be removed.
/// </remarks>
/// <param name="types">The list of <see cref="Type"/> instances to expose as part of this service.</param>
public StaticTypeLookupService(
IEnumerable<Type>? types = null
) {
/*------------------------------------------------------------------------------------------------------------------------
| Populate collection
\-----------------------------------------------------------------------------------------------------------------------*/
if (types is not null) {
foreach (var type in types) {
if (!Contains(type)) {
Add(type);
}
}
}
}
/// <summary>
/// Establishes a new instance of a <see cref="StaticTypeLookupService"/>. Optionally accepts a list of <see cref="Type"/>
/// instances and a default <see cref="Type"/> value.
/// </summary>
/// <remarks>
/// Any <see cref="Type"/> instances submitted via <paramref name="types"/> should be unique by <see
/// cref="MemberInfo.Name"/>; if they are not, they will be removed.
/// </remarks>
/// <param name="types">The list of <see cref="Type"/> instances to expose as part of this service.</param>
/// <param name="defaultType">The default type to return if no match can be found. Defaults to object.</param>
[ExcludeFromCodeCoverage]
[Obsolete(
$"The {nameof(DefaultType)} property has been removed. Fallbacks types can now be added to {nameof(Lookup)} directly.",
true
)]
public StaticTypeLookupService(
IEnumerable<Type>? types,
Type? defaultType
) {
throw new NotImplementedException();
}
/*==========================================================================================================================
| PROPERTY: DEFAULT TYPE
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// The default type to return in case <see cref="Lookup(String[])"/> cannot find a match.
/// </summary>
[ExcludeFromCodeCoverage]
[Obsolete(
$"The {nameof(DefaultType)} property has been removed. Fallbacks types can now be added to {nameof(Lookup)} directly.",
true
)]
public Type? DefaultType { get; }
/*==========================================================================================================================
| METHOD: LOOKUP
\-------------------------------------------------------------------------------------------------------------------------*/
/// <inheritdoc/>
public virtual Type? Lookup(params string[] typeNames) {
if (typeNames is not null) {
foreach (var typeName in typeNames) {
if (Contains(typeName)) {
return _typeCollection[typeName];
}
}
}
return null;
}
/*==========================================================================================================================
| METHOD: ADD
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Adds a <see cref="Type"/> to the underlying collection.
/// </summary>
[ExcludeFromCodeCoverage]
protected void Add(Type type) => _typeCollection.Add(type);
/*==========================================================================================================================
| METHOD: TRY ADD
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Determines if a <see cref="Type"/> with the given <see cref="MemberInfo.Name"/> exists. If it does, returns <c>false
/// </c>; otherwise, adds the <see cref="Type"/> and returns <c>true</c>.
/// </summary>
protected bool TryAdd(Type type) {
Contract.Requires(type, nameof(type));
if (Contains(type.Name)) {
return false;
}
Add(type);
return true;
}
/*==========================================================================================================================
| METHOD: ADD OR REPLACE
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Determines if a <see cref="Type"/> with the given <see cref="MemberInfo.Name"/> exists. If it does, it is replaced.
/// Otherwise, it is added.
/// </summary>
protected void AddOrReplace(Type type) {
Contract.Requires(type, nameof(type));
if (_typeCollection.Contains(type.Name)) {
Remove(type.Name);
}
Add(type);
}
/*==========================================================================================================================
| METHOD: CONTAINS
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Determines if the underlying collection has a <see cref="Type"/>.
/// </summary>
/// <param name="type">The <see cref="Type"/> to located in the collection.</param>
/// <returns><c>True</c> if the <see cref="Type"/> exists in the collection.</returns>
[ExcludeFromCodeCoverage]
protected bool Contains(Type type) => _typeCollection.Contains(type);
/// <summary>
/// Determines if the underlying collection has a <see cref="Type"/> with the provided <paramref name="key"/>.
/// </summary>
/// <param name="key">The key of the <see cref="Type"/> to located in the collection.</param>
/// <returns><c>True</c> if a <see cref="Type"/> with <paramref name="key"/> exists in the collection.</returns>
[ExcludeFromCodeCoverage]
protected bool Contains(string key) => _typeCollection.Contains(key);
/*==========================================================================================================================
| METHOD: REMOVE
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Removes a <see cref="Type"/> with the provided <paramref name="key"/>.
/// </summary>
[ExcludeFromCodeCoverage]
protected void Remove(string key) => _typeCollection.Remove(key);
} //Class
} //Namespace