Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -242,32 +242,32 @@ private static bool IsDiscriminator(InputProperty property)

private ModelProvider? BuildBaseModelProvider()
{
if (_inputModel.BaseModel == null)
// consider models that have been customized to inherit from a different model
if (CustomCodeView?.BaseType != null)
{
// consider models that have been customized to inherit from a different model
if (CustomCodeView?.BaseType != null)
{
var baseType = CustomCodeView.BaseType;
var baseType = CustomCodeView.BaseType;

// If the custom base type doesn't have a resolved namespace, then try to resolve it from the input model map.
// This will happen if a model is customized to inherit from another generated model, but that generated model
// was not also defined in custom code so Roslyn does not recognize it.
if (string.IsNullOrEmpty(baseType.Namespace))
{
if (CodeModelGenerator.Instance.TypeFactory.InputModelTypeNameMap.TryGetValue(baseType.Name, out var baseInputModel))
{
baseType = CodeModelGenerator.Instance.TypeFactory.CreateCSharpType(baseInputModel);
}
}
if (baseType != null && CodeModelGenerator.Instance.TypeFactory.CSharpTypeMap.TryGetValue(
baseType,
out var customBaseType) &&
customBaseType is ModelProvider customBaseModel)
// If the custom base type doesn't have a resolved namespace, then try to resolve it from the input model map.
// This will happen if a model is customized to inherit from another generated model, but that generated model
// was not also defined in custom code so Roslyn does not recognize it.
if (string.IsNullOrEmpty(baseType.Namespace))
{
if (CodeModelGenerator.Instance.TypeFactory.InputModelTypeNameMap.TryGetValue(baseType.Name, out var baseInputModel))
{
return customBaseModel;
baseType = CodeModelGenerator.Instance.TypeFactory.CreateCSharpType(baseInputModel);
}
}
if (baseType != null && CodeModelGenerator.Instance.TypeFactory.CSharpTypeMap.TryGetValue(
baseType,
out var customBaseType) &&
customBaseType is ModelProvider customBaseModel)
{
return customBaseModel;
}
}

if (_inputModel.BaseModel == null)
{
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,38 @@ public async Task DiscriminatorPropertyNotGeneratedIfOnCustomizedBase()
Assert.AreEqual("Sample.Models", modelProvider.BaseType!.Namespace);
}

[Test]
public async Task CanCustomizeBaseModelWithSpecBase()
{
var specBaseModel = InputFactory.Model(
"specBaseModel",
properties: [InputFactory.Property("specBaseProp", InputPrimitiveType.String)],
usage: InputModelTypeUsage.Json);
var customBaseModel = InputFactory.Model(
"customBaseModel",
properties: [InputFactory.Property("customBaseProp", InputPrimitiveType.String)],
usage: InputModelTypeUsage.Json);
var childModel = InputFactory.Model(
"mockInputModel",
properties: [InputFactory.Property("childProp", InputPrimitiveType.String)],
baseModel: specBaseModel,
usage: InputModelTypeUsage.Json);

var mockGenerator = await MockHelpers.LoadMockGeneratorAsync(
inputModelTypes: [childModel, specBaseModel, customBaseModel],
compilation: async () => await Helpers.GetCompilationFromDirectoryAsync());

var modelProvider = mockGenerator.Object.OutputLibrary.TypeProviders.Single(t => t.Name == "MockInputModel");

// should have customized base type, not the spec base type
Assert.IsNotNull(modelProvider.BaseType);
Assert.IsNotNull(modelProvider.BaseTypeProvider);
Assert.AreEqual("CustomBaseModel", modelProvider.BaseType!.Name);
Assert.AreEqual("Sample.Models", modelProvider.BaseType!.Namespace);
Assert.AreEqual(1, modelProvider.BaseTypeProvider!.Properties.Count);
Assert.AreEqual("CustomBaseProp", modelProvider.BaseTypeProvider.Properties[0].Name);
}

private class NameSpaceVisitor : LibraryVisitor
{
protected override TypeProvider? VisitType(TypeProvider type)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#nullable disable

using Sample;
using SampleTypeSpec;

namespace Sample.Models
{
public partial class MockInputModel : CustomBaseModel
{
}
}
Loading