Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

Custom mappings should be able to use generated mapper

Open schehlmj opened this issue 3 years ago • 0 comments

When using Mapster.Tool to generate a mapper from interface, I need to be able to some complex custom mapping code.

The BeforeMapping and AfterMapping config in the Register are helpful to a point, but they don't allow using other generated mapping methods generated for the interface.

I worked around this, but it's less than ideal:

  interface ICustomMapper
   { 
      Bar Map(Foo src, object noMapperGeneration = null);  // the noMapperGeneration param prevents this method from code generating
   }

  interface IMapper : ICustomMapper
  {  
       Bar Map(Foo src);  // this gets code generated
   }

  partial class Mapper : ICustomMapper  // the partial class mean that the generated code is available
  { 
    private readonly IGeneratedMapper _genMapper;  // access to the methods in generated partial class with different interface

    public Mapper()
    {
       _generatedMapper = (IGeneratedMapper)(object)this; 
    }
 
    public Bar Map(Foo src, object noMapperGeneration = null)
    {
        var bar = _generatedMapper.Map(src);  // this uses the generated mapper code
        bar.Baz = ComplexLogicUsingMapperMethods(src);  
     } 

    public string ComplexLogicUsingMapperMethods(Foo src)
    {
         // the code in here can use of the custom mapping methods 
         // and any of the generated mapper code through _generatedMapper  
     }
  }

I am hoping that some solution can be made to make this cleaner.

Here is my proposed code:


  [Mapper]
  interface IMapper 
  {  
       Bar Map(Foo src); 
   }

   partial class Mapper : IMapper   
   { 
      public Bar BeforeMap(Foo src)  // by naming convention, the code generation would know to call this at the beginning of the generated "Bar Map(Foo src)" method
      {   ....
      }

      public Bar AfterMap(Foo src)  // by naming convention, the code generation would know to call this at the end of the generated "Bar Map(Foo src)" method
      {
          bar.Baz = ComplexLogicUsingMapperMethods(src);  
      } 

      public string = ComplexLogicUsingMapperMethods(Foo src)
      {
           // the code in here can use the code in this class
           // and any of the generated mapper code in this class
       }
   }

schehlmj avatar Aug 23 '22 19:08 schehlmj