Mapping to inherited interface not working

See original GitHub issue

I have the following mapping config defined

config.NewConfig<OrderStatusSaveDto, IOrderStatus>()
    .ConstructUsing(src => null);

(NB ConstructUsing(src => null) is because I don’t want the mapper to be in control of constructing the interface, it will always be passed an instance)

And then in a controller I receive an OrderStatusSaveDto from the post body (which is populated). I then retrieve an IOrderStatus entity from a service and call the following to map the properties over

orderStatus.Adapt(entity);

After this call however, the entity hasn’t been populated at all.

Should Mapster be able to map to an interface like this?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
chaowlertcommented, May 15, 2019

This is might actually a bug. Mapster use type.GetProperties(...) to retrieve all properties. This method for class, it will also return inherited properties. However for interface, it will only return declare properties.

Fixing this issue might has side effect, I will see how to fix this.

0reactions
IsmailHassanicommented, Apr 7, 2020

Hi @chaowlert, My apologies for my late response. It has to do with the multiple projects i’m working on currently. Today i took your unittest to check if this worked. I had to add an inherited interface without extra properties and tried to adapt it to an model. Same error occurs here. It is not covered by the current tests because you do dto > interface. I’m trying to map interface > dto.

        [TestMethod]
        public void MapToInheritedInterfaceWithoutProperties()
        {
            var config = TypeAdapterConfig.GlobalSettings;
            TypeAdapterConfig<IInheritedDtoWithoutProperties, InheritedDto>.NewConfig()
                .Map(d => d.Id, s => s.Id)
                .Map(d => d.Name, s => s.Name)
                .IgnoreNonMapped(true);

            config.Compile();

            /// doesn't reach this point
            var dto = new InheritedDto
            {
                Id = 1,
                Name = "Test",
                DateOfBirth = new DateTime(1978, 12, 10),
                UnmappedSource = "Lorem ipsum"
            } as IInheritedDtoWithoutProperties;

            var idto = dto.Adapt<InheritedDto>(config);
        }

        public interface IInheritedDtoWithoutProperties : IDto
        {
        }

Maybe that’s why it does not work? Btw it happens on compilation of the typeadapter.

The exception thrown is:

'Id' is not a member of type 'Mapster.Tests.WhenMappingToInterface+IInheritedDtoWithoutProperties'
Parameter name: propertyOrFieldName
   at System.Linq.Expressions.Expression.PropertyOrField(Expression expression, String propertyOrFieldName)
   at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable`1 source, TAccumulate seed, Func`3 func)
   at Mapster.Utils.ExpressionEx.PropertyOrFieldPath(Expression expr, String path) in C:\Projects\Mapster\src\Mapster\Utils\ExpressionEx.cs:line 23
   at Mapster.Models.InvokerModel.GetInvokingExpression(Expression exp, MapType mapType) in C:\Projects\Mapster\src\Mapster\Models\InvokerModel.cs:line 37
   at Mapster.ValueAccessingStrategy.CustomResolverFn(Expression source, IMemberModel destinationMember, CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Settings\ValueAccessingStrategy.cs:line 42
   at Mapster.Adapters.BaseClassAdapter.<>c__DisplayClass4_1.<CreateClassConverter>b__2(Func`4 fn, Expression src) in C:\Projects\Mapster\src\Mapster\Adapters\BaseClassAdapter.cs:line 40
   at System.Linq.Enumerable.<SelectManyIterator>d__167`3.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at Mapster.Adapters.BaseClassAdapter.CreateClassConverter(Expression source, ClassModel classModel, CompileArgument arg, Expression destination) in C:\Projects\Mapster\src\Mapster\Adapters\BaseClassAdapter.cs:line 38
   at Mapster.Adapters.ClassAdapter.CreateInlineExpression(Expression source, CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\ClassAdapter.cs:line 169
   at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\BaseAdapter.cs:line 304
   at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\BaseAdapter.cs:line 107
   at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\BaseAdapter.cs:line 28
   at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg) in C:\Projects\Mapster\src\Mapster\TypeAdapterConfig.cs:line 349
Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Inherited Interface property not found by Model Binding
Take a look at AutoMapper for what classes your views should be mapping to. The quick summary: create view-specific models (i.e. View Models) ......
Read more >
C# | Inheritance in interfaces
When a class implements the inherited interface then it must provide the implementation of all the members that are defined within the interface...
Read more >
Hibernate Inheritance Mapping
A practical guide to understanding different inheritance mapping strategies with JPA / Hibernate.
Read more >
Interfaces - C# language specification
An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces. Interfaces can contain methods, ...
Read more >
Mapping GDMO Templates to IDL Interfaces
In CORBA IDL, an attribute or operation cannot be inherited from more than one interface, whereas in GDMO such multiple declaration is allowed....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found