From 814c1012f1e4f9157b2e15c201c139eda48c8605 Mon Sep 17 00:00:00 2001
From: desjoerd <sjoerd.meer@outlook.com>
Date: Mon, 2 Dec 2024 17:34:44 +0100
Subject: [PATCH] Fix TypeMapper UseReference not used when mapping a
 GenericType

---
 .../Generation/TypeMapperTests.cs             | 43 +++++++++++++++++++
 .../Generation/JsonTypeDescription.cs         |  7 +++
 2 files changed, 50 insertions(+)

diff --git a/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs b/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs
index 56a4e936d..af93dd26a 100644
--- a/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs
+++ b/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs
@@ -124,5 +124,48 @@ public async Task When_generic_type_mapper_is_defined_then_it_is_called_and_the_
             Assert.False(schema.Definitions.ContainsKey("MyWrapperOfMyBar"));
         }
 
+        public class MyStringFoo
+        {
+            public MyWrapper<string> PropertyString { get; set; }
+
+            public MyWrapper<MyBar> PropertyMyBar { get; set; }
+        }
+
+        public class WithoutReferenceTypeMapper : ITypeMapper
+        {
+            public Type MappedType => typeof(MyWrapper<>);
+
+            public bool UseReference => false;
+
+            public void GenerateSchema(JsonSchema schema, TypeMapperContext context)
+            {
+                context.JsonSchemaGenerator.Generate(schema, context.Type.GenericTypeArguments[0], context.JsonSchemaResolver);
+            }
+        }
+
+
+        [Fact]
+        public async Task When_generic_type_mapper_is_defined_then_it_is_called_and_the_use_reference_false_is_used()
+        {
+            // Act
+            var schema = NewtonsoftJsonSchemaGenerator.FromType<MyStringFoo>(new NewtonsoftJsonSchemaGeneratorSettings
+            {
+                TypeMappers =
+                {
+                    new WithoutReferenceTypeMapper()
+                }
+            });
+
+            // Assert
+            var json = schema.ToJson();
+            Assert.False(schema.Definitions.ContainsKey("string"));
+            Assert.False(schema.Definitions.ContainsKey("MyWrapperOfString"));
+            Assert.True(schema.Definitions.ContainsKey("MyBar"));
+
+            Assert.Contains("$ref", json); // The $ref to MyBar should be present
+            // There should only be one $ref, which is to Bar, this is the case when the first and last index of "$ref" is the same
+            Assert.True(json.IndexOf("$ref", StringComparison.Ordinal) == json.LastIndexOf("$ref", StringComparison.Ordinal));
+        }
+
     }
 }
diff --git a/src/NJsonSchema/Generation/JsonTypeDescription.cs b/src/NJsonSchema/Generation/JsonTypeDescription.cs
index 5cd0b3dc3..a8180919b 100644
--- a/src/NJsonSchema/Generation/JsonTypeDescription.cs
+++ b/src/NJsonSchema/Generation/JsonTypeDescription.cs
@@ -6,6 +6,7 @@
 // <author>Rico Suter, mail@rsuter.com</author>
 //-----------------------------------------------------------------------
 
+using System.Reflection;
 using Namotion.Reflection;
 using NJsonSchema.Generation.TypeMappers;
 
@@ -91,6 +92,12 @@ public static JsonTypeDescription CreateForEnumeration(ContextualType type, Json
         public bool RequiresSchemaReference(IEnumerable<ITypeMapper> typeMappers)
         {
             var typeMapper = typeMappers.FirstOrDefault(m => m.MappedType == ContextualType.OriginalType);
+            if (typeMapper == null && ContextualType.OriginalType.GetTypeInfo().IsGenericType)
+            {
+                var genericType = ContextualType.OriginalType.GetGenericTypeDefinition();
+                typeMapper = typeMappers.FirstOrDefault(m => m.MappedType == genericType);
+            }
+
             if (typeMapper != null)
             {
                 return typeMapper.UseReference;