Skip to content

Commit c58659d

Browse files
committed
Avoid some cases of Type -> AssemblyQualifiedTypeName-> Type conversion in MappingByCode
1 parent f0f2a53 commit c58659d

File tree

2 files changed

+63
-37
lines changed

2 files changed

+63
-37
lines changed

src/NHibernate/Mapping/ByCode/Impl/TypeNameUtil.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static class TypeNameUtil
88
public static string GetNhTypeName(this System.Type type)
99
{
1010
string typeName;
11-
IType nhType = TypeFactory.HeuristicType(type.AssemblyQualifiedName);
11+
IType nhType = TypeFactory.HeuristicType(type);
1212
if (nhType != null)
1313
{
1414
typeName = nhType.Name;
@@ -68,4 +68,4 @@ private static string GetTypeNameForMapping(System.Type type)
6868
return type.Name;
6969
}
7070
}
71-
}
71+
}

src/NHibernate/Type/TypeFactory.cs

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,22 @@ public static IType HeuristicType(string typeName)
522522
return HeuristicType(typeName, null);
523523
}
524524

525+
/// <summary>
526+
/// Uses heuristics to deduce a NHibernate type given a string naming the
527+
/// type.
528+
/// </summary>
529+
/// <param name="type"></param>
530+
/// <returns>An instance of <c>NHibernate.Type.IType</c></returns>
531+
/// <remarks>
532+
/// We check to see if it implements IType, ICompositeUserType, IUserType, ILifecycle (Association), or
533+
/// IPersistentEnum. If none of those are implemented then we will serialize the Type to the
534+
/// database using NHibernate.Type.SerializableType(typeName)
535+
/// </remarks>
536+
public static IType HeuristicType(System.Type type)
537+
{
538+
return HeuristicType(type, typeName: null, parameters: null, length: null);
539+
}
540+
525541
/// <summary>
526542
/// Uses heuristics to deduce a NHibernate type given a string naming the type.
527543
/// </summary>
@@ -532,7 +548,7 @@ public static IType HeuristicType(string typeName, IDictionary<string, string> p
532548
{
533549
return HeuristicType(typeName, parameters, null);
534550
}
535-
551+
536552
/// <summary>
537553
/// Uses heuristics to deduce a NHibernate type given a string naming the type.
538554
/// </summary>
@@ -542,50 +558,63 @@ public static IType HeuristicType(string typeName, IDictionary<string, string> p
542558
/// <returns></returns>
543559
public static IType HeuristicType(string typeName, IDictionary<string, string> parameters, int? length)
544560
{
545-
IType type = Basic(typeName, parameters);
561+
return HeuristicType(/*resolvedType:*/ null, typeName, parameters, length);
562+
}
546563

547-
if (type != null)
548-
return type;
549-
550-
string[] parsedTypeName;
551-
TypeClassification typeClassification = GetTypeClassification(typeName);
552-
if (typeClassification == TypeClassification.LengthOrScale)
553-
parsedTypeName = typeName.Split(LengthSplit);
554-
else
555-
parsedTypeName = typeClassification == TypeClassification.PrecisionScale ? typeName.Split(PrecisionScaleSplit) : new[] { typeName };
564+
/// <summary>
565+
/// Provide either resolvedType or typeName. resolvedType takes precedence.
566+
/// </summary>
567+
private static IType HeuristicType(System.Type resolvedType, string typeName, IDictionary<string, string> parameters, int? length)
568+
{
569+
if (resolvedType == null)
570+
{
571+
IType type = Basic(typeName, parameters);
556572

573+
if (type != null)
574+
return type;
557575

558-
System.Type typeClass;
559-
try
560-
{
561-
typeClass = ReflectHelper.ClassForName(parsedTypeName[0]); //typeName);
562-
}
563-
catch (Exception)
564-
{
565-
typeClass = null;
566-
}
576+
string[] parsedTypeName;
577+
var typeClassification = GetTypeClassification(typeName);
578+
if (typeClassification == TypeClassification.LengthOrScale)
579+
{
580+
parsedTypeName = typeName.Split(LengthSplit);
581+
if(!int.TryParse(parsedTypeName[1], out int parsedLength))
582+
{
583+
throw new MappingException($"Could not parse length value '{parsedTypeName[1]}' as int for type '{typeName}'");
584+
}
585+
length = parsedLength;
586+
}
587+
else
588+
parsedTypeName = typeClassification == TypeClassification.PrecisionScale ? typeName.Split(PrecisionScaleSplit) : new[] { typeName };
567589

568-
if (typeClass == null)
569-
return null;
570-
590+
try
591+
{
592+
resolvedType = ReflectHelper.ClassForName(parsedTypeName[0]); //typeName);
593+
}
594+
catch (Exception)
595+
{
596+
return null;
597+
}
598+
}
599+
var typeClass = resolvedType;
571600
if (typeof(IType).IsAssignableFrom(typeClass))
572601
{
573602
try
574603
{
575-
type = (IType) Environment.ObjectsFactory.CreateInstance(typeClass);
604+
var type = (IType) Environment.ObjectsFactory.CreateInstance(typeClass);
605+
InjectParameters(type, parameters);
606+
607+
var obsolete = typeClass.GetCustomAttribute<ObsoleteAttribute>(false);
608+
if (obsolete != null)
609+
{
610+
_log.Warn("{0} is obsolete. {1}", typeName, obsolete.Message);
611+
}
612+
return type;
576613
}
577614
catch (Exception e)
578615
{
579616
throw new MappingException("Could not instantiate IType " + typeClass.Name + ": " + e, e);
580617
}
581-
InjectParameters(type, parameters);
582-
583-
var obsolete = typeClass.GetCustomAttribute<ObsoleteAttribute>(false);
584-
if (obsolete != null)
585-
{
586-
_log.Warn("{0} is obsolete. {1}", typeName, obsolete.Message);
587-
}
588-
return type;
589618
}
590619
if (typeof(ICompositeUserType).IsAssignableFrom(typeClass))
591620
{
@@ -609,9 +638,6 @@ public static IType HeuristicType(string typeName, IDictionary<string, string> p
609638
if (!typeClass.IsSerializable)
610639
return null;
611640

612-
if (typeClassification == TypeClassification.LengthOrScale)
613-
return GetSerializableType(typeClass, Int32.Parse(parsedTypeName[1]));
614-
615641
if (length.HasValue)
616642
return GetSerializableType(typeClass, length.Value);
617643

0 commit comments

Comments
 (0)