Skip to content

ConstructUsing for generic types doesn't work #507

Closed

Description

@omerercelik

TypeAdapterConfig<PagedList<ExampleEntity>, PagedList<ExampleDto>>.ForType().ConstructUsing(dest => new PagedList<ExampleDto>(new List<ExampleDto>(), 1, 1)); = > its work

TypeAdapterConfig<PagedList<Type>, PagedList<Type>>.ForType().ConstructUsing(dest => new PagedList<Type>(new List<Type>(), 1, 1)); it doesn't work and throw Exception

Exception => System.InvalidOperationException : No default constructor for type 'PagedList`1', please use 'ConstructUsing' or 'MapWith'

pagedlist constructors;

    `public PagedList(IEnumerable<T> items, int page, int size)
        : this(items.AsQueryable(), page, size)
    {
    }

    public PagedList(IEnumerable<T> items, int page, int size, int itemCount)
    {
        BindItems(page, size, itemCount);
        Items = items;
    }

    public PagedList(IQueryable<T> items, int page, int size)
    {
        var itemCount = items.Count();
        BindItems(page, size, itemCount);

        Items = items.PagedBy(page, size).ToList();
    } `

Activity

  1. changed the title [-]ConstructUsing[/-] [+]ConstructUsing for generic types doesn't work[/+] on Dec 12, 2022
  2. andrerav commented on Jan 3, 2023

    @andrerav
    Member

    @omerercelik Which version of Mapster are you using?

  3. self-assigned this
    on Jan 3, 2023
  4. omerercelik commented on Jan 3, 2023

    @omerercelik
    Author

    @andrerav I am using 7.3.0

  5. DocSvartz commented on Oct 23, 2023

    @DocSvartz
    Contributor

    @omerercelik You can set Full sample of this case. propably i found the source of this problem )

  6. DocSvartz commented on Oct 23, 2023

    @DocSvartz
    Contributor

    @andrerav This seems to be related to the reason why the tests I commented out in this do not work #646 . the same error is generated there.
    I made a simplified version of the bypass previously installed in the class adapter and then there was no error.

  7. DocSvartz commented on Oct 24, 2023

    @DocSvartz
    Contributor

    TypeAdapterConfig<PagedList<Type>, PagedList<Type>>.ForType().ConstructUsing(dest => new PagedList<Type>(new List<Type>(), 1, 1)); it doesn't work and throw Exception

    If Type is System.Type? then as far as I understand it cannot be created. This can only be obtained. typeof(), .Gettype()

    valid Generic definition possible must look like as typeof(PagedList<>), and mapping from this and mapping for this should be supported endofpage

    TypeAdapterConfig.GlobalSettings.ForType(typeof(GenericPoco<>), typeof(GenericDto<>))
        .Map("value", "Value");
    
  8. omerercelik commented on Oct 25, 2023

    @omerercelik
    Author

    TypeAdapterConfig.GlobalSettings.ForType(typeof(GenericPoco<>), typeof(GenericDto<>)) Does not have ConstructUsing definition.
    @DocSvartz When I use this syntax i can not use ConstructUsing method.

    How can I use contructusing method in generic classes? Or How can i skip this error when generic class have one more constructor?

    Exception => System.InvalidOperationException : No default constructor for type 'PagedList`1', please use 'ConstructUsing' or 'MapWith'

  9. DocSvartz commented on Oct 25, 2023

    @DocSvartz
    Contributor

    Even if you bring it to a case that in theory should work.

    You get IQueryable from the conversion function and there will always be an error Instead of the data you need

    [TestClass]
    public class WhenGenericMapping
    {
    
    
        [TestMethod]
        public void TestMappingGeneric()
        {
            TypeAdapterConfig
                .GlobalSettings
                .ForDestinationType(typeof(SamplePageList<>))
                .MapToConstructor(true);
    
            SamplePageList<string> _SourcePageList = new(new[] { "1234", "222" }.ToList(), 2, 2);
                      
             var _DeconstructPageList = _SourcePageList.Adapt<PocoActivatorPageList<string>>();
             var _result = _DeconstructPageList.Adapt<SamplePageList<string>>();
    
            _DeconstructPageList.Items.ToArray()[0].ShouldBe("1234"); 
            _DeconstructPageList.Items.ToArray()[1].ShouldBe("222"); 
    
            _result.Items.ToArray()[0].ShouldBe("1234"); // Error 
            _result.Items.ToArray()[1].ShouldBe("222"); //  Error 
    
        }
    
    }
    
    
        class PocoActivatorPageList<T>
        {
            public  IEnumerable<T> Items { get; set; }
            public int Size { get; set; }
            public int Page { get; set; }
    
        }
    
    
        class SamplePageList<T>
        {
    
            public IQueryable<T> Items { get;  private set; }
    
            public int Size {  get; private set; }
            public int Page {  get; private set; }
    
            public int ItemCount { get; private set; }
    
            public SamplePageList(IEnumerable<T> items, int page, int size)
            : this(items.AsQueryable(), page, size)
            {
                // this target
            }
    
            public SamplePageList(IEnumerable<T> items, int page, int size, int itemCount)
            {
               /// Not used
            }
    
            public SamplePageList(IQueryable<T> items, int page, int size)
            {
                Items = items;
                ItemCount = items.Count();
                Page = page;
                Size = size;
            } 
        }
    
    
    
    Error Message:
     System.NotImplementedException: The method or operation is not implemented.
    Trace Stack:
      GeneratedType_1.GetEnumerator()
      LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
      EnumerableHelpers.ToArray[T](IEnumerable`1 source)
      Enumerable.ToArray[TSource](IEnumerable`1 source)
      WhenGenericMapping.TestMappingGeneric() 
    
    From this File Mapster.Utils.DynamicTypeGenerator
    
  10. DocSvartz commented on Oct 25, 2023

    @DocSvartz
    Contributor

    @andrerav For some reason, RecordType is involved there again)))
    for interface IQueryable

  11. DocSvartz commented on Oct 26, 2023

    @DocSvartz
    Contributor

    @andrerav Apparently it is necessary to allocate a separate InterfaceAdapter (Base logic work from all Interface) handler with private setters (uses from RecordTypeAdapter).
    I'll try this as step 3 of fix #537.
    In continuation of this PR #646.

  12. DocSvartz commented on Oct 26, 2023

    @DocSvartz
    Contributor

    @omerercelik This working From This

    @andrerav I managed to separate the processing of interfaces without public setters from the processing of RecordTypes)

    But IQueryable now not supported

    [TestClass]
    public class WhenGenericMapping
    {
    
    
        [TestMethod]
        public void TestMappingGeneric()
        {
    
            TypeAdapterConfig
                .GlobalSettings
                .ForType(typeof(SamplePageList<>), typeof(SamplePageList<>))
                .ShallowCopyForSameType(true);
    
            SamplePageList<string> _SourcePageList = new(new[] { "1234", "222" }.ToList(), 2, 2);
            SamplePageList<int> _SourcePageList2 = new(new[] { 555, 333 }.ToList(), 2, 2);
                       
            var c = _SourcePageList.Adapt(_SourcePageList2);
    
            c.Items.ToArray()[0].ShouldBe(1234);
            c.Items.ToArray()[1].ShouldBe(222);
    
        }
    
    }
    
    
    class PocoActivatorPageList<T>
    {
        public  IEnumerable<T> Items { get; set; }
        public int Size { get; set; }
        public int Page { get; set; }
    
    }
    
    
    class SamplePageList<T>
    {
    
        public IEnumerable<T> Items { get;  private set; }
    
        public int Size {  get; private set; }
        public int Page {  get; private set; }
    
        public int ItemCount { get; private set; }
    
        public SamplePageList(IEnumerable<T> items, int page, int size)
            
        {
            Items = items;
            ItemCount = items.Count();
            Page = page;
            Size = size;
        }
    
        public SamplePageList(IEnumerable<T> items, int page, int size, int itemCount)
        {
           /// Not used
        }
    
        public SamplePageList(IQueryable<T> items, int page, int size)
        {
            Items = items;
            ItemCount = items.Count();
            Page = page;
            Size = size;
        } 
    }
    
    
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions