Skip to content

GetAPI generates invalid code when interface property is implemented in a base class #2066

@pakrym

Description

@pakrym

Consider the following class structure:

    public class PagePropertyModel : ParameterModelBase, ICommonModel
    {
        // ...
        public PageApplicationModel Page { get; set; }

        MemberInfo ICommonModel.MemberInfo => PropertyInfo;

        public PropertyInfo PropertyInfo { get; }

        public string PropertyName
        {
            get => Name;
            set => Name = value;
        }
   }

    public abstract class ParameterModelBase : IBindingModel
    {
        // ...
        public IReadOnlyList<object> Attributes { get; }

        public IDictionary<object, object> Properties { get; }

        public Type ParameterType { get; }

        public string Name { get; protected set;  }

        public BindingInfo BindingInfo { get; set; }
    }


    public interface ICommonModel : IPropertyModel
    {
        IReadOnlyList<object> Attributes { get; }
        MemberInfo MemberInfo { get; }
        string Name { get; }
    }

    public interface IBindingModel
    {
        BindingInfo BindingInfo { get; set; }
    }

In it ICommonModel.Attributes and ICommonModel.Properties gets implemented by ParameterModelBase when PagePropertyModel inherits from it and implements ICommonModel.

GenAPI produces the following generated code:

   [System.Diagnostics.DebuggerDisplayAttribute("PagePropertyModel: Name={PropertyName}")]
    public partial class PagePropertyModel : Microsoft.AspNetCore.Mvc.ApplicationModels.ParameterModelBase, Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel, Microsoft.AspNetCore.Mvc.ApplicationModels.IPropertyModel
    {
        public PagePropertyModel(Microsoft.AspNetCore.Mvc.ApplicationModels.PagePropertyModel other) : base (default(System.Type), default(System.Collections.Generic.IReadOnlyList<object>)) { }
        public PagePropertyModel(System.Reflection.PropertyInfo propertyInfo, System.Collections.Generic.IReadOnlyList<object> attributes) : base (default(System.Type), default(System.Collections.Generic.IReadOnlyList<object>)) { }
        System.Reflection.MemberInfo Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.MemberInfo { get { throw null; } }
        public Microsoft.AspNetCore.Mvc.ApplicationModels.PageApplicationModel Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
        public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
        public string PropertyName { get { throw null; } set { } }
        System.Collections.Generic.IReadOnlyList<object> Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.get_Attributes() { throw null; }
        System.Collections.Generic.IDictionary<object, object> Microsoft.AspNetCore.Mvc.ApplicationModels.IPropertyModel.get_Properties() { throw null; }
    }

Problem is that get_Attributes and get_Properties are not generated as properties.

I tracked the problem to TypeExtensions.GetAccessorType method: methodDefinition.ContainingTypeDefinition.Properties doesn't contain Attributes and so accessor kind detection fails.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-Infrastructure-librariesArea maintained by .NET libraries team: APICompat, AsmDiff, GenAPI, GenFacades, PkgProj, etc

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions