From 54d9e2cc0167f60ca2e1d031c740aaf3cf31c26f Mon Sep 17 00:00:00 2001 From: Beth Maloney Date: Thu, 29 Feb 2024 12:41:36 +1100 Subject: [PATCH] Replace Constructor Info Invoke with CreateInstance --- .../Utils/ExtensionsTests.cs | 48 +++++++++++++++++++ .../MissingConstructorException.cs | 8 +++- src/FluentNHibernate/Utils/Extensions.cs | 16 ++++--- 3 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 src/FluentNHibernate.Testing/Utils/ExtensionsTests.cs 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 9296b8dc6..586cc666e 100644 --- a/src/FluentNHibernate/MissingConstructorException.cs +++ b/src/FluentNHibernate/MissingConstructorException.cs @@ -8,8 +8,12 @@ public class MissingConstructorException : Exception { 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) + { } protected MissingConstructorException(SerializationInfo info, StreamingContext context) : base(info, context) - {} + { } } diff --git a/src/FluentNHibernate/Utils/Extensions.cs b/src/FluentNHibernate/Utils/Extensions.cs index 8b82f4ef1..096c277e4 100644 --- a/src/FluentNHibernate/Utils/Extensions.cs +++ b/src/FluentNHibernate/Utils/Extensions.cs @@ -53,12 +53,14 @@ public static T InstantiateUsingParameterlessConstructor(this Type type) public static object InstantiateUsingParameterlessConstructor(this Type type) { - var constructor = ReflectHelper.GetDefaultConstructor(type); - - if (constructor == 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) @@ -75,7 +77,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);