diff --git a/src/Our.Umbraco.Ditto/ComponentModel/Attributes/DittoProcessorAttribute.cs b/src/Our.Umbraco.Ditto/ComponentModel/Attributes/DittoProcessorAttribute.cs
index 17a6c44..9754926 100644
--- a/src/Our.Umbraco.Ditto/ComponentModel/Attributes/DittoProcessorAttribute.cs
+++ b/src/Our.Umbraco.Ditto/ComponentModel/Attributes/DittoProcessorAttribute.cs
@@ -21,7 +21,7 @@ protected DittoProcessorAttribute()
{
if (Ditto.TryGetTypeAttribute(this.GetType(), out DittoProcessorMetaDataAttribute metaData, true) == false || metaData == null)
{
- throw new ApplicationException("Ditto processor attributes require a DittoProcessorMetaData attribute to be applied to the class but none was found.");
+ throw new ApplicationException($"The Ditto processor attribute ('{this.GetType()}') requires a DittoProcessorMetaData attribute to be applied to the class but none was found.");
}
this.ValueType = metaData.ValueType;
diff --git a/src/Our.Umbraco.Ditto/ComponentModel/ObjectResolution/AttributedTypeResolver.cs b/src/Our.Umbraco.Ditto/ComponentModel/ObjectResolution/AttributedTypeResolver.cs
index 6dab172..b5c5814 100644
--- a/src/Our.Umbraco.Ditto/ComponentModel/ObjectResolution/AttributedTypeResolver.cs
+++ b/src/Our.Umbraco.Ditto/ComponentModel/ObjectResolution/AttributedTypeResolver.cs
@@ -12,20 +12,26 @@ namespace Our.Umbraco.Ditto
/// A specific Ditto attribute type.
internal sealed class AttributedTypeResolver where TAttribute : Attribute
{
- private readonly ConcurrentDictionary _attributedTypeLookup;
+ private readonly object _lock = new object();
+
+ private readonly Dictionary _attributedTypeLookup;
private AttributedTypeResolver()
{
- _attributedTypeLookup = new ConcurrentDictionary();
+ _attributedTypeLookup = new Dictionary();
}
private void Initialize(IEnumerable types, bool inherit = false)
{
- if (types != null)
+ // NOTE: Lock when initializing the resolver, so that it can't be read from (at the same time).
+ lock (_lock)
{
- foreach (var type in types)
+ if (types != null)
{
- TryAddAttributedType(type, out TAttribute attribute, inherit);
+ foreach (var type in types)
+ {
+ TryAddAttributedType(type, out TAttribute attribute, inherit);
+ }
}
}
}
@@ -83,7 +89,8 @@ private bool TryAddAttributedType(Type type, out TAttribute attribute, bool inhe
{
if (_attributedTypeLookup.ContainsKey(type) == false)
{
- return _attributedTypeLookup.TryAdd(type, attribute);
+ _attributedTypeLookup.Add(type, attribute);
+ return true;
}
else
{
@@ -103,14 +110,18 @@ private bool TryAddAttributedType(Type type, out TAttribute attribute, bool inhe
/// Returns the associated attribute for the given object-type.
public bool TryGetTypeAttribute(Type type, out TAttribute attribute, bool inherit = false)
{
- bool result = _attributedTypeLookup.TryGetValue(type, out attribute);
-
- if (result == false)
+ // NOTE: Lock when looking up from the resolver, to avoid concurrency issues.
+ lock (_lock)
{
- result = TryAddAttributedType(type, out attribute, inherit);
- }
+ bool result = _attributedTypeLookup.TryGetValue(type, out attribute);
- return result;
+ if (result == false)
+ {
+ result = TryAddAttributedType(type, out attribute, inherit);
+ }
+
+ return result;
+ }
}
}
}
\ No newline at end of file