diff --git a/src/JsonApiDotNetCore/Graph/TypeLocator.cs b/src/JsonApiDotNetCore/Graph/TypeLocator.cs
index 5bdb029e50..223845859a 100644
--- a/src/JsonApiDotNetCore/Graph/TypeLocator.cs
+++ b/src/JsonApiDotNetCore/Graph/TypeLocator.cs
@@ -45,7 +45,6 @@ private static Type[] GetAssemblyTypes(Assembly assembly)
return types;
}
-
///
/// Get all implementations of . in the assembly
///
@@ -80,15 +79,28 @@ public static List GetIdentifableTypes(Assembly assembly)
///
public static (Type implementation, Type registrationInterface) GetGenericInterfaceImplementation(Assembly assembly, Type openGenericInterfaceType, params Type[] genericInterfaceArguments)
{
+ if(assembly == null) throw new ArgumentNullException(nameof(assembly));
+ if(openGenericInterfaceType == null) throw new ArgumentNullException(nameof(openGenericInterfaceType));
+ if(genericInterfaceArguments == null) throw new ArgumentNullException(nameof(genericInterfaceArguments));
+ if(genericInterfaceArguments.Length == 0) throw new ArgumentException("No arguments supplied for the generic interface.", nameof(genericInterfaceArguments));
+ if(openGenericInterfaceType.IsGenericType == false) throw new ArgumentException("Requested type is not a generic type.", nameof(openGenericInterfaceType));
+
foreach (var type in assembly.GetTypes())
{
var interfaces = type.GetInterfaces();
foreach (var interfaceType in interfaces)
- if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == openGenericInterfaceType)
- return (
- type,
- interfaceType.MakeGenericType(genericInterfaceArguments)
- );
+ {
+ if (interfaceType.IsGenericType)
+ {
+ var genericTypeDefinition = interfaceType.GetGenericTypeDefinition();
+ if(genericTypeDefinition == openGenericInterfaceType.GetGenericTypeDefinition()) {
+ return (
+ type,
+ genericTypeDefinition.MakeGenericType(genericInterfaceArguments)
+ );
+ }
+ }
+ }
}
return (null, null);
diff --git a/test/UnitTests/Graph/TypeLocator_Tests.cs b/test/UnitTests/Graph/TypeLocator_Tests.cs
new file mode 100644
index 0000000000..f0d1ce04ad
--- /dev/null
+++ b/test/UnitTests/Graph/TypeLocator_Tests.cs
@@ -0,0 +1,99 @@
+using System;
+using JsonApiDotNetCore.Graph;
+using JsonApiDotNetCore.Models;
+using Xunit;
+
+namespace UnitTests.Internal
+{
+ public class TypeLocator_Tests
+ {
+ [Fact]
+ public void GetGenericInterfaceImplementation_Gets_Implementation()
+ {
+ // arrange
+ var assembly = GetType().Assembly;
+ var openGeneric = typeof(IGenericInterface<>);
+ var genericArg = typeof(int);
+
+ var expectedImplementation = typeof(Implementation);
+ var expectedInterface = typeof(IGenericInterface);
+
+ // act
+ var result = TypeLocator.GetGenericInterfaceImplementation(
+ assembly,
+ openGeneric,
+ genericArg
+ );
+
+ // assert
+ Assert.NotNull(result);
+ Assert.Equal(expectedImplementation, result.implementation);
+ Assert.Equal(expectedInterface, result.registrationInterface);
+ }
+
+ [Fact]
+ public void GetDerivedGenericTypes_Gets_Implementation()
+ {
+ // arrange
+ var assembly = GetType().Assembly;
+ var openGeneric = typeof(BaseType<>);
+ var genericArg = typeof(int);
+
+ var expectedImplementation = typeof(DerivedType);
+
+ // act
+ var results = TypeLocator.GetDerivedGenericTypes(
+ assembly,
+ openGeneric,
+ genericArg
+ );
+
+ // assert
+ Assert.NotNull(results);
+ var result = Assert.Single(results);
+ Assert.Equal(expectedImplementation, result);
+ }
+
+ [Fact]
+ public void GetIdType_Correctly_Identifies_JsonApiResource()
+ {
+ // arrange
+ var type = typeof(Model);
+ var exextedIdType = typeof(int);
+
+ // act
+ var result = TypeLocator.GetIdType(type);
+
+ // assert
+ Assert.NotNull(result);
+ Assert.True(result.isJsonApiResource);
+ Assert.Equal(exextedIdType, result.idType);
+ }
+
+ [Fact]
+ public void GetIdType_Correctly_Identifies_NonJsonApiResource()
+ {
+ // arrange
+ var type = typeof(DerivedType);
+ Type exextedIdType = null;
+
+ // act
+ var result = TypeLocator.GetIdType(type);
+
+ // assert
+ Assert.NotNull(result);
+ Assert.False(result.isJsonApiResource);
+ Assert.Equal(exextedIdType, result.idType);
+ }
+ }
+
+
+ public interface IGenericInterface { }
+ public class Implementation : IGenericInterface { }
+
+
+ public class BaseType { }
+ public class DerivedType : BaseType { }
+
+ public class Model : Identifiable { }
+}
\ No newline at end of file