diff --git a/Runtime/Utilities/ReflectionUtility.cs b/Runtime/Utilities/ReflectionUtility.cs
index 8b4d3f2..b929151 100644
--- a/Runtime/Utilities/ReflectionUtility.cs
+++ b/Runtime/Utilities/ReflectionUtility.cs
@@ -11,19 +11,28 @@ namespace StansAssets.Foundation
///
public static class ReflectionUtility
{
- static readonly string[] s_BuiltInAssemblyPrefixes = { "Mono.", "Unity.", "UnityEngine", "UnityEditor", "System", "mscorlib" };
+ ///
+ /// Collection of predefined built-in assembly prefixes. Mono., UnityEditor., Unity., UnityEngine, System and mscorlib prefixes included.
+ ///
+ public static readonly string[] BuiltInAssemblyPrefixes = { "Mono.", "UnityEditor.", "Unity.", "UnityEngine", "System", "mscorlib" };
///
/// Creates an instance of the specified using that type's parameterless constructor.
///
/// Full type name of the instance to create.
/// New instance of the specified type.
+ /// parameter is null.
+ /// specified with doesn't have default parameterless constructor.
public static object CreateInstance(string typeFullName)
{
+ if (typeFullName == null)
+ throw new ArgumentNullException(nameof(typeFullName));
+
var type = FindType(typeFullName);
- return type != null && type.HasDefaultConstructor()
- ? Activator.CreateInstance(type)
- : null;
+ if (!type.HasDefaultConstructor())
+ throw new ArgumentException($"Type {typeFullName} doesn't have default parameterless constructor.");
+
+ return Activator.CreateInstance(type);
}
///
@@ -31,40 +40,45 @@ public static object CreateInstance(string typeFullName)
///
/// Full type's name to search for.
/// object found via specified .
+ /// parameter is null.
+ /// No types matching found in current application domain.
public static Type FindType(string typeFullName)
{
+ if (typeFullName == null)
+ throw new ArgumentNullException(nameof(typeFullName));
+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
return assemblies
.SelectMany(assembly => assembly.GetTypes())
- .FirstOrDefault(type => type.FullName == null || type.FullName.Equals(typeFullName));
+ .First(type => type.FullName == null || type.FullName.Equals(typeFullName));
}
///
/// Searched for the implementations of the specified with .
///
- /// true if the built-in assemblies have to be skipped. If set to false, no assemblies will be skipped.
+ /// Collection of assembly prefixes to skip. The will be ignored if its name starts with one of these prefixes.
/// Specifies the whose implementations to search for.
/// A collection of objects that are implementations of .
- public static IEnumerable FindImplementationsOf(bool ignoreBuiltIn = false)
+ public static IEnumerable FindImplementationsOf(IEnumerable ignoreAssemblyPrefixes = null)
{
var baseType = typeof(T);
- return FindImplementationsOf(baseType, ignoreBuiltIn);
+ return FindImplementationsOf(baseType, ignoreAssemblyPrefixes);
}
///
/// Gets the assemblies that have been loaded into the execution context of this application domain.
///
- /// true if the built-in assemblies have to be skipped. If set to false, no assemblies will be skipped.
+ /// Collection of assembly prefixes to skip. The will be ignored if its name starts with one of these prefixes.
/// A collection of assemblies in this application domain.
- public static IEnumerable GetAssemblies(bool ignoreBuiltIn = false)
+ public static IEnumerable GetAssemblies(IEnumerable ignoreAssemblyPrefixes = null)
{
IEnumerable assemblies = AppDomain.CurrentDomain.GetAssemblies();
- if (ignoreBuiltIn)
+ if (ignoreAssemblyPrefixes != null)
{
assemblies = assemblies.Where(assembly => {
var assemblyName = assembly.GetName().Name;
- return !s_BuiltInAssemblyPrefixes.Any(prefix => assemblyName.StartsWith(prefix));
+ return !BuiltInAssemblyPrefixes.Any(prefix => assemblyName.StartsWith(prefix));
});
}
@@ -75,11 +89,15 @@ public static IEnumerable GetAssemblies(bool ignoreBuiltIn = false)
/// Searched for the implementations of the specified with .
///
/// Specifies the whose implementations to search for.
- /// true if the built-in assemblies have to be skipped. If set to false, no assemblies will be skipped.
+ /// Collection of assembly prefixes to skip. The will be ignored if its name starts with one of these prefixes.
/// A collection of objects that are implementations of .
- public static IEnumerable FindImplementationsOf(Type baseType, bool ignoreBuiltIn = false)
+ /// parameter is null.
+ public static IEnumerable FindImplementationsOf(Type baseType, IEnumerable ignoreAssemblyPrefixes = null)
{
- var assemblies = GetAssemblies(ignoreBuiltIn);
+ if (baseType == null)
+ throw new ArgumentNullException(nameof(baseType));
+
+ var assemblies = GetAssemblies(ignoreAssemblyPrefixes);
return assemblies
.SelectMany(assembly => assembly.GetTypes())
@@ -93,9 +111,22 @@ public static IEnumerable FindImplementationsOf(Type baseType, bool ignore
/// The string containing the name of the public property to get.
/// A bitwise combination of the enumeration values that specify how the search is conducted.
/// The property value of the specified object.
+ /// parameter is null.
+ /// The target object is null.
+ /// Property specified with the not found.
public static object GetPropertyValue(object src, string propName, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public)
{
- return src.GetType().GetProperty(propName, bindingAttr)?.GetValue(src, null);
+ if (propName == null)
+ throw new ArgumentNullException(nameof(propName));
+
+ if (src == null)
+ throw new TargetException($"Target {nameof(src)} object is null.");
+
+ var property = src.GetType().GetProperty(propName, bindingAttr);
+ if (property == null)
+ throw new ArgumentException($"Property with '{propName}' name not found");
+
+ return property.GetValue(src, null);
}
///
@@ -106,9 +137,22 @@ public static object GetPropertyValue(object src, string propName, BindingFlags
/// The new property value.
/// A bitwise combination of the enumeration values that specify how the search is conducted.
/// Specifies the of property value to set.
+ /// parameter is null.
+ /// The target object is null.
+ /// Property specified with the not found.
public static void SetPropertyValue(object src, string propName, T propValue, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public)
{
- src.GetType().GetProperty(propName, bindingAttr)?.SetValue(src, propValue);
+ if (propName == null)
+ throw new ArgumentNullException(nameof(propName));
+
+ if (src == null)
+ throw new TargetException($"Target {nameof(src)} object is null.");
+
+ var property = src.GetType().GetProperty(propName, bindingAttr);
+ if (property == null)
+ throw new ArgumentException($"Property with '{propName}' name not found");
+
+ property.SetValue(src, propValue);
}
///
@@ -116,12 +160,12 @@ public static void SetPropertyValue(object src, string propName, T propValue,
///
/// A bitwise combination of the enumeration values that specify how the search is conducted.
/// true to search this member's inheritance chain to find the attributes; otherwise, false.
- /// true if the built-in assemblies have to be skipped. If set to false, no assemblies will be skipped.
+ /// Collection of assembly prefixes to skip. The will be ignored if its name starts with one of these prefixes.
/// Specifies the of the custom attribute to search for.
/// A collection of objects representing all methods defined for the current that match the specified binding constraints and attributes type.
- public static IEnumerable FindMethodsWithCustomAttributes(BindingFlags methodBindingFlags = BindingFlags.Instance | BindingFlags.Public, bool inherit = true, bool ignoreBuiltIn = false) where T : Attribute
+ public static IEnumerable FindMethodsWithCustomAttributes(BindingFlags methodBindingFlags = BindingFlags.Instance | BindingFlags.Public, bool inherit = true, IEnumerable ignoreAssemblyPrefixes = null) where T : Attribute
{
- var assemblies = GetAssemblies(ignoreBuiltIn);
+ var assemblies = GetAssemblies(ignoreAssemblyPrefixes);
return assemblies
.SelectMany(assembly => assembly.GetTypes())
diff --git a/Tests/Editor/Utilities/ReflectionUtilityTests.cs b/Tests/Editor/Utilities/ReflectionUtilityTests.cs
index 7066834..702761e 100644
--- a/Tests/Editor/Utilities/ReflectionUtilityTests.cs
+++ b/Tests/Editor/Utilities/ReflectionUtilityTests.cs
@@ -95,7 +95,7 @@ public void CreateInstanceValid(Type type)
[TestCase(typeof(ClassWithPrivateConstructor))]
public void CreateInstanceInvalid(Type type)
{
- Assert.IsNull(ReflectionUtility.CreateInstance(type.FullName), $"Failed to create instance for:{type.FullName}");
+ Assert.Throws(() => ReflectionUtility.CreateInstance(type.FullName), $"Failed to create instance for:{type.FullName}");
}
[TestCase("System.Int32")]
@@ -108,7 +108,7 @@ public void FindTypeValid(string fullTypeName)
[TestCase("System.ClassDoesNotExist")]
public void FindTypeInvalid(string fullTypeName)
{
- Assert.IsNull(ReflectionUtility.FindType(fullTypeName), $"Type {fullTypeName} not found");
+ Assert.Throws(() => ReflectionUtility.FindType(fullTypeName), $"Type {fullTypeName} should NOT be found in this case");
}
class TestAssembly
@@ -148,7 +148,7 @@ public void GetAllAssemblies()
[Test]
public void GetAllAssembliesWithoutBuiltIn()
{
- var assemblies = ReflectionUtility.GetAssemblies(true).ToList();
+ var assemblies = ReflectionUtility.GetAssemblies(ReflectionUtility.BuiltInAssemblyPrefixes).ToList();
Assert.True(assemblies.Any(), "Assemblies collection is empty");
var assembliesSearchMap = new Dictionary();
@@ -270,8 +270,8 @@ public void SetPropertyValue()
[Test]
public void FindMethodsWithCustomAttributes()
{
- var allMethodInfos = ReflectionUtility.FindMethodsWithCustomAttributes(ignoreBuiltIn: true).ToList();
- var nonInheritedMethodInfos = ReflectionUtility.FindMethodsWithCustomAttributes(inherit: false, ignoreBuiltIn: true).ToList();
+ var allMethodInfos = ReflectionUtility.FindMethodsWithCustomAttributes(ignoreAssemblyPrefixes: ReflectionUtility.BuiltInAssemblyPrefixes).ToList();
+ var nonInheritedMethodInfos = ReflectionUtility.FindMethodsWithCustomAttributes(inherit: false, ignoreAssemblyPrefixes: ReflectionUtility.BuiltInAssemblyPrefixes).ToList();
Assert.True(allMethodInfos.Count == 2, "Incorrect amount of methods with custom attribute (inheritances included)");
Assert.True(nonInheritedMethodInfos.Count == 1, "Incorrect amount of methods with custom attribute (inheritances NOT included)");