Skip to content

Conversation

@Angelinsky7
Copy link
Contributor

Pr to implement #4325
from discussion from here : https://github.com/AutoMapper/AutoMapper/discussions/4323

The idea is to add 2 parameters to the ExplicitExpansion call :

Boolean explicitExpansion = true : instead of the hardcode true value we can control the value there
Boolean overrideExpansion = true: only used inside `ForAllMembers` like that we can decide if we override all the previous call to explicitExpansion or keep the value

and now we could do something like that

cfg.CreateMap<Source, Dto>()
        .ForMember(dto => dto.Desc, conf => conf.ExplicitExpansion())
        .ForMember(dto => dto.Name, conf => conf.MapFrom(src => src.Name))
        .ForMember(dto => dto.Code, conf => conf.ExplicitExpansion(false))
        .ForAllMembers(conf => conf.ExplicitExpansion(overrideExpansion: false));
});

and only the Code field will be implicitly expanded.

From my point of view, all tests passe (DI, Intergration, Unit) and some simple test were added to demonstrate.

I'm pretty sure this request misses something to be me merge as it is, but i hope that you will help.

Copy link
Contributor

@lbargaoanu lbargaoanu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First change the base branch to basic_include.

/// </summary>
void ExplicitExpansion();
/// <param name="explicitExpansion">Is explicitExpansion active</param>
void ExplicitExpansion(Boolean explicitExpansion = true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool value = true

}

public void ExplicitExpansion() => _ctorParamActions.Add(cpm => cpm.ExplicitExpansion = true);
public void ExplicitExpansion(Boolean explicitExpansion = true) => _ctorParamActions.Add(cpm => cpm.ExplicitExpansion = explicitExpansion);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it work without the default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it also work... i thought that if i added this to the IMemberConfigurationExpression it was good to add this here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in the new pr

void ExplicitExpansion();
/// <param name="explicitExpansion">Is explicitExpansion active</param>
/// <param name="overrideExpansion">Does explicitExpansion can override settings already set by another ExplicitExpansion call</param>
void ExplicitExpansion(Boolean explicitExpansion = true, Boolean overrideExpansion = true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove overrideExpansion.

Copy link
Contributor Author

@Angelinsky7 Angelinsky7 Aug 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if i remove overrideExpansion the all thing doesn't work anymore.
because
.ForAllMembers(conf => conf.ExplicitExpansion())
will override all config and we won't be able to just disable one item (and let all the other be ExplicitExpansion=true)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the intended behaviour with ForAllMembers. The only usage for resetting explicit expansion is with mapping inheritance.

Copy link
Contributor Author

@Angelinsky7 Angelinsky7 Aug 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes i know, but i have a lot of usecase where i would like to have 100 fields with ExplicitExpansion and only one Implicit.
Sadly ForAllMembers does not permit this. so i thought that i could add the possibility to configure ExplicitExpansion for inheritance and also for disabling only one field.
if i could chain calls after ForAllMembers i want have to do this. But because it was explicitly marked as void, i thought it was intended.

Copy link
Contributor

@lbargaoanu lbargaoanu Aug 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you can simply add an if in ForAllMembers to skip setting ExplicitExpansion when you don't need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you can simply add an if in ForAllMembers to skip setting ExpliitExpansion when you don't need it.

What ??!!! I didn't know that i could already do that... (or i didn't understand you correctly)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think i was not clear enough... what i was trying to solve is this kind of code :

CreateMap<TCheckSet, CheckSetFromCheckRequestDto>()
  .ForMember(dest => dest.Id, m => { m.MapFrom(src => src.Id); m.ExplicitExpansion(); })
  .ForMember(dest => dest.Equipment, m => { m.MapFrom(src => src.Equipment); m.ExplicitExpansion(); })
  .ForMember(dest => dest.PlannedDate, m => { m.MapFrom(src => src.PlannedDate); m.ExplicitExpansion(); })
  .ForMember(dest => dest.IsChecked, m => { m.MapFrom(src => src.IsChecked); m.ExplicitExpansion(); })
  .ForMember(dest => dest.ActualDate, m => { m.MapFrom(src => src.ActualDate); m.ExplicitExpansion(); })
  .ForMember(dest => dest.Status, m => { m.MapFrom(src => src.StatusId); m.ExplicitExpansion(); })
  .ForMember(dest => dest.Comments, m => { m.MapFrom(src => src.Comments); m.ExplicitExpansion(); })
  .ForMember(dest => dest.ActiveTypes, m => { m.MapFrom(src => src.ActiveTypes.Select(p => (TypeOfCheckTypeDto)p.Id)); })
  .ForMember(dest => dest.Jobs, m => { m.MapFrom(src => src.Jobs); m.ExplicitExpansion(); });
//.ForAllMembers(p => p.ExplicitExpansion());

CreateMap<TCheckSet, CheckSetDto>()
  .IncludeBase<TCheckSet, CheckSetFromCheckRequestDto>()
  .ForMember(dest => dest.CheckRequest, m => { m.MapFrom(src => src.CheckRequest); m.ExplicitExpansion(); });
  //.ForAllMembers(p => p.ExplicitExpansion());

and would like to write this kind instead

CreateMap<TCheckSet, CheckSetFromCheckRequestDto>()
   .ForMember(dest => dest.Id, m => m.MapFrom(src => src.Id))
   .ForMember(dest => dest.Equipment, m => m.MapFrom(src => src.Equipment))
   .ForMember(dest => dest.PlannedDate, m => m.MapFrom(src => src.PlannedDate))
   .ForMember(dest => dest.IsChecked, m => m.MapFrom(src => src.IsChecked))
   .ForMember(dest => dest.ActualDate, m => m.MapFrom(src => src.ActualDate))
   .ForMember(dest => dest.Status, m => m.MapFrom(src => src.StatusId))
   .ForMember(dest => dest.Comments, m => m.MapFrom(src => src.Comments))
   .ForMember(dest => dest.ActiveTypes, m => { m.MapFrom(src => src.ActiveTypes.Select(p => (TypeOfCheckTypeDto)p.Id)); m.ExplicitExpansion(false))
   .ForMember(dest => dest.Jobs, m => m.MapFrom(src => src.Jobs))
   .ForAllMembers(p => p.ExplicitExpansion());

CreateMap<TCheckSet, CheckSetDto>()
    .IncludeBase<TCheckSet, CheckSetFromCheckRequestDto>()
    .ForMember(dest => dest.CheckRequest, m => m.MapFrom(src => src.CheckRequest))
    .ForMember(dest => dest.Jobs, m => { m.MapFrom(src => src.Jobs);  m.ExplicitExpansion(false)})
    .ForAllMembers(p => p.ExplicitExpansion());

notice the subtle change for the ActiveTypes field and the use of ForAllMembers (and of course now the possibility to disable ExplicitExpansion for some fields)
but actually, if i'm doing this the settings of ActiveTypes is reset when i call ForAllMembers (witch the inheritance too, which could be more problematic)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i could even add , in this case i could rewrite the all thing like this

CreateMap<TCheckSet, CheckSetFromCheckRequestDto>()
   .ForMember(dest => dest.ActiveTypes, m => { m.MapFrom(src => src.ActiveTypes.Select(p => (TypeOfCheckTypeDto)p.Id)); m.ExplicitExpansion(false))
   .ForAllMembers(p => p.ExplicitExpansion());

CreateMap<TCheckSet, CheckSetDto>()
    .IncludeBase<TCheckSet, CheckSetFromCheckRequestDto>()
    .ForMember(dest => dest.CheckRequest, m => m.MapFrom(src => src.CheckRequest))
    .ForMember(dest => dest.Jobs, m => { m.MapFrom(src => src.Jobs);  m.ExplicitExpansion(false)})
    .ForAllMembers(p => p.ExplicitExpansion());

which feel really clean.. instead of all the config lines

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need ForAllMembers in the derived map. And all the explicit config goes against AM's purpose. I've already explained how the PR should look.

@@ -0,0 +1,130 @@
using System.Text.RegularExpressions;
Copy link
Contributor

@lbargaoanu lbargaoanu Aug 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid you chose the wrong test as model :) Start here instead.
You need to use Include and override in the derived map. Assert that both the base map and the derived map work as intended.
Also add a test for constructor mapping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can also add this, but i also had other requirements for this pr... this is why i chose this test. i understand now that it has more impact that i thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new test have been created in the new pr

Copy link
Contributor

@lbargaoanu lbargaoanu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First change the base branch to basic_include.

@LuckyPennySoftware LuckyPennySoftware deleted a comment from Angelinsky7 Aug 3, 2023
@Angelinsky7 Angelinsky7 changed the base branch from master to basic_include August 3, 2023 13:57
@Angelinsky7 Angelinsky7 closed this by deleting the head repository Aug 3, 2023
@Angelinsky7
Copy link
Contributor Author

First change the base branch to basic_include.

i think i mess up the base branch change, i would need to recreate the pr, but i would like to continue the discussion here first

@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants