Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions Dapper NET40/SqlMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,8 @@ where pair.Value > 1

static SqlMapper()
{
SetDefaultTypeMap(t => new DefaultTypeMap(t));

typeMap = new Dictionary<Type, DbType>();
typeMap[typeof(byte)] = DbType.Byte;
typeMap[typeof(sbyte)] = DbType.SByte;
Expand Down Expand Up @@ -3554,7 +3556,7 @@ static readonly MethodInfo
getItem = typeof(IDataRecord).GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.GetIndexParameters().Any() && p.GetIndexParameters()[0].ParameterType == typeof(int))
.Select(p => p.GetGetMethod()).First();

/// <summary>
/// Gets type-map for the given type
/// </summary>
Expand All @@ -3580,14 +3582,25 @@ public static ITypeMap GetTypeMap(Type type)

if (map == null)
{
map = new DefaultTypeMap(type);
map = _defaultTypeMapFactory(type);
_typeMaps[type] = map;
}
}
}
return map;
}

private static Func<Type, ITypeMap> _defaultTypeMapFactory;

/// <summary>
/// Set a custom mapping for all types
/// </summary>
/// <param name="factory">A function that creates the ITypeMap</param>
public static void SetDefaultTypeMap(Func<Type, ITypeMap> factory)
{
_defaultTypeMapFactory = factory;
}

// use Hashtable to get free lockless reading
#if DNXCORE50
private static readonly Dictionary<Type,ITypeMap> _typeMaps = new Dictionary<Type, ITypeMap>();
Expand All @@ -3604,8 +3617,8 @@ public static void SetTypeMap(Type type, ITypeMap map)
{
if (type == null)
throw new ArgumentNullException("type");

if (map == null || map is DefaultTypeMap)
if (map == null)
{
lock (_typeMaps)
{
Expand Down Expand Up @@ -5335,7 +5348,7 @@ public ParameterInfo Parameter
/// <summary>
/// Represents default type mapping strategy used by Dapper
/// </summary>
sealed partial class DefaultTypeMap : SqlMapper.ITypeMap
partial class DefaultTypeMap : SqlMapper.ITypeMap
{
private readonly List<FieldInfo> _fields;
private readonly List<PropertyInfo> _properties;
Expand Down Expand Up @@ -5404,7 +5417,7 @@ internal static List<FieldInfo> GetSettableFields(Type t)
/// <param name="names">DataReader column names</param>
/// <param name="types">DataReader column types</param>
/// <returns>Matching constructor or default one</returns>
public ConstructorInfo FindConstructor(string[] names, Type[] types)
public virtual ConstructorInfo FindConstructor(string[] names, Type[] types)
{
var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (ConstructorInfo ctor in constructors.OrderBy(c => c.IsPublic ? 0 : (c.IsPrivate ? 2 : 1)).ThenBy(c => c.GetParameters().Length))
Expand Down Expand Up @@ -5466,7 +5479,7 @@ public ConstructorInfo FindExplicitConstructor()
/// <param name="constructor">Constructor to resolve</param>
/// <param name="columnName">DataReader column name</param>
/// <returns>Mapping implementation</returns>
public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
public virtual SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
{
var parameters = constructor.GetParameters();

Expand All @@ -5478,7 +5491,7 @@ public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor,
/// </summary>
/// <param name="columnName">DataReader column name</param>
/// <returns>Mapping implementation</returns>
public SqlMapper.IMemberMap GetMember(string columnName)
public virtual SqlMapper.IMemberMap GetMember(string columnName)
{
var property = _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.Ordinal))
?? _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase));
Expand Down