diff --git a/Dapper/PublicAPI.Unshipped.txt b/Dapper/PublicAPI.Unshipped.txt
index 91b0e1a43..6fd5aa3bc 100644
--- a/Dapper/PublicAPI.Unshipped.txt
+++ b/Dapper/PublicAPI.Unshipped.txt
@@ -1 +1,2 @@
-#nullable enable
\ No newline at end of file
+#nullable enable
+static Dapper.SqlMapper.AddTypeHandlerImpl(System.Type! type, Dapper.SqlMapper.ITypeHandler? handler) -> void
\ No newline at end of file
diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs
index 47e40ea41..ebcf7f675 100644
--- a/Dapper/SqlMapper.cs
+++ b/Dapper/SqlMapper.cs
@@ -255,22 +255,19 @@ static SqlMapper()
[typeof(TimeOnly?)] = TypeMapEntry.DoNotSetFieldValue,
#endif
};
- ResetTypeHandlers(false);
+ ResetTypeHandlers();
}
///
/// Clear the registered type handlers.
///
- public static void ResetTypeHandlers() => ResetTypeHandlers(true);
-
[MemberNotNull(nameof(typeHandlers))]
- private static void ResetTypeHandlers(bool clone)
- {
+ public static void ResetTypeHandlers() {
typeHandlers = [];
- AddTypeHandlerImpl(typeof(DataTable), new DataTableHandler(), clone);
- AddTypeHandlerImpl(typeof(XmlDocument), new XmlDocumentHandler(), clone);
- AddTypeHandlerImpl(typeof(XDocument), new XDocumentHandler(), clone);
- AddTypeHandlerImpl(typeof(XElement), new XElementHandler(), clone);
+ AddTypeHandlerImpl(typeof(DataTable), new DataTableHandler());
+ AddTypeHandlerImpl(typeof(XmlDocument), new XmlDocumentHandler());
+ AddTypeHandlerImpl(typeof(XDocument), new XDocumentHandler());
+ AddTypeHandlerImpl(typeof(XElement), new XElementHandler());
}
///
@@ -339,7 +336,7 @@ public static void RemoveTypeMap(Type type)
///
/// The type to handle.
/// The handler to process the .
- public static void AddTypeHandler(Type type, ITypeHandler handler) => AddTypeHandlerImpl(type, handler, true);
+ public static void AddTypeHandler(Type type, ITypeHandler handler) => AddTypeHandlerImpl(type, handler);
///
/// Determine if the specified type will be processed by a custom handler.
///
@@ -353,7 +350,15 @@ public static void RemoveTypeMap(Type type)
/// The type to handle.
/// The handler to process the .
/// Whether to clone the current type handler map.
- public static void AddTypeHandlerImpl(Type type, ITypeHandler? handler, bool clone)
+ [Obsolete("Please use overload of " + nameof(AddTypeHandlerImpl) + " without the clone parameter. This API may be removed at a later date.")]
+ public static void AddTypeHandlerImpl(Type type, ITypeHandler? handler, bool clone) => AddTypeHandlerImpl(type, handler);
+
+ ///
+ /// Configure the specified type to be processed by a custom handler.
+ ///
+ /// The type to handle.
+ /// The handler to process the .
+ public static void AddTypeHandlerImpl(Type type, ITypeHandler? handler)
{
if (type is null) throw new ArgumentNullException(nameof(type));
@@ -373,10 +378,21 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler? handler, bool clo
}
}
- var snapshot = typeHandlers;
- if (snapshot.TryGetValue(type, out var oldValue) && handler == oldValue) return; // nothing to do
-
- var newCopy = clone ? new Dictionary(snapshot) : snapshot;
+ lock (typeHandlers)
+ {
+ if (typeHandlers.TryGetValue(type, out var oldValue) && handler == oldValue) return; // nothing to do
+
+ if (handler is null)
+ {
+ typeHandlers.Remove(type);
+ if (secondary is not null) typeHandlers.Remove(secondary);
+ }
+ else
+ {
+ typeHandlers[type] = handler;
+ if (secondary is not null) typeHandlers[secondary] = handler;
+ }
+ }
#pragma warning disable 618
typeof(TypeHandlerCache<>).MakeGenericType(type).GetMethod(nameof(TypeHandlerCache.SetHandler), BindingFlags.Static | BindingFlags.NonPublic)!.Invoke(null, [handler]);
@@ -385,17 +401,6 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler? handler, bool clo
typeof(TypeHandlerCache<>).MakeGenericType(secondary).GetMethod(nameof(TypeHandlerCache.SetHandler), BindingFlags.Static | BindingFlags.NonPublic)!.Invoke(null, [handler]);
}
#pragma warning restore 618
- if (handler is null)
- {
- newCopy.Remove(type);
- if (secondary is not null) newCopy.Remove(secondary);
- }
- else
- {
- newCopy[type] = handler;
- if (secondary is not null) newCopy[secondary] = handler;
- }
- typeHandlers = newCopy;
}
///
@@ -403,7 +408,7 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler? handler, bool clo
///
/// The type to handle.
/// The handler for the type .
- public static void AddTypeHandler(TypeHandler handler) => AddTypeHandlerImpl(typeof(T), handler, true);
+ public static void AddTypeHandler(TypeHandler handler) => AddTypeHandlerImpl(typeof(T), handler);
private static Dictionary typeHandlers;
@@ -479,7 +484,7 @@ public static void SetDbType(IDataParameter parameter, object value)
{
handler = (ITypeHandler)Activator.CreateInstance(
typeof(SqlDataRecordHandler<>).MakeGenericType(argTypes))!;
- AddTypeHandlerImpl(type, handler, true);
+ AddTypeHandlerImpl(type, handler);
return DbType.Object;
}
catch