diff --git a/src/FluentNHibernate.Testing/Utils/ExtensionsTests.cs b/src/FluentNHibernate.Testing/Utils/ExtensionsTests.cs new file mode 100644 index 000000000..19c3f0a02 --- /dev/null +++ b/src/FluentNHibernate.Testing/Utils/ExtensionsTests.cs @@ -0,0 +1,48 @@ +using NUnit.Framework; +using FluentNHibernate.Utils; + +namespace FluentNHibernate.Testing.Utils; + +[TestFixture] +public class ExtensionsTests +{ + class PublicConstructor + { + public PublicConstructor() { } + } + + class PrivateConstructor + { + private PrivateConstructor() { } + } + + class ConstructorWithArguments + { + private ConstructorWithArguments(int number) { } + } + + [Test] + public void CanInitialiseClass() + { + var type = typeof(PublicConstructor); + var result = type.InstantiateUsingParameterlessConstructor(); + + Assert.That(result, Is.InstanceOf()); + } + + [Test] + public void CanInitialiseClassWithPrivateConstructor() + { + var type = typeof(PrivateConstructor); + var result = type.InstantiateUsingParameterlessConstructor(); + + Assert.That(result, Is.InstanceOf()); + } + + [Test] + public void ClassWithoutParameterlessConstructorThrowsException() + { + var type = typeof(ConstructorWithArguments); + Assert.Throws(() => type.InstantiateUsingParameterlessConstructor()); + } +} diff --git a/src/FluentNHibernate/MissingConstructorException.cs b/src/FluentNHibernate/MissingConstructorException.cs index 2887b1ae4..0ac9fffbc 100644 --- a/src/FluentNHibernate/MissingConstructorException.cs +++ b/src/FluentNHibernate/MissingConstructorException.cs @@ -10,6 +10,10 @@ public MissingConstructorException(Type type) : base("'" + type.AssemblyQualifiedName + "' is missing a parameterless constructor.") { } + public MissingConstructorException(Type type, Exception innerException) + : base("'" + type.AssemblyQualifiedName + "' is missing a parameterless constructor.", innerException) + { } + [Obsolete("This API supports obsolete formatter-based serialization and will be removed in a future version")] protected MissingConstructorException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/FluentNHibernate/Utils/Extensions.cs b/src/FluentNHibernate/Utils/Extensions.cs index 345305c05..0f3daf11e 100644 --- a/src/FluentNHibernate/Utils/Extensions.cs +++ b/src/FluentNHibernate/Utils/Extensions.cs @@ -59,12 +59,14 @@ public static T InstantiateUsingParameterlessConstructor(this Type type) public static object InstantiateUsingParameterlessConstructor(this Type type) { - var constructor = ReflectHelper.GetDefaultConstructor(type); - - if (constructor is null) - throw new MissingConstructorException(type); - - return constructor.Invoke(null); + try + { + return Activator.CreateInstance(type, true); + } + catch (MissingMethodException ex) + { + throw new MissingConstructorException(type, ex); + } } public static bool HasInterface(this Type type, Type interfaceType) @@ -81,7 +83,7 @@ public static T DeepClone(this T obj) #if NETFRAMEWORK var formatter = new BinaryFormatter(); #else - var formatter = new BinaryFormatter(new NetStandardSerialization.SurrogateSelector(), new StreamingContext()); + var formatter = new BinaryFormatter(new NetStandardSerialization.SurrogateSelector(), new StreamingContext()); #endif formatter.Serialize(stream, obj);