-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Implement ShouldUseConstructor #2698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Allows for constructors to be excluded in the same way as properties and fields (ShouldMapField & ShouldMapProperty).
I think I got all the places where Couldn't find a sensible place for the tests to live, so I just put them with the big random list of tests in the bugs folder. I'm not sure why Happy to make changes if required. |
/// Specify which constructors should be mapped. | ||
/// By default all non-static constructors are mapped. | ||
/// </summary> | ||
Func<ConstructorInfo, bool> ShouldMapCtor { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ShouldUseConstructor is a better name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, I used Ctor because other places in AM use Ctor in place of Constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, an oversight :)
docs/Configuration.md
Outdated
## Global property/field/constructor filtering | ||
|
||
By default, AutoMapper tries to map every public property/field. You can filter out properties/fields with the property/field filters: | ||
By default, AutoMapper tries to map every public property/field, and all non-static declared constructors. You can filter out properties/fields/constructors with the property/field/constructor filters: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the wording is strange, AM doesn't map constructors, it uses them to construct destination objects. Also there is a special page for constructors, so the content should be there, not here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll move it, I agree.
src/AutoMapper/ProfileMap.cs
Outdated
} | ||
|
||
private void BuildTypeMap(IConfigurationProvider configurationProvider, ITypeMapConfiguration config) | ||
using System; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know GitHub sometimes messes the diff, but if you could fix it somehow, that would be nice :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll see what I can do. I am assuming it's line endings, but no idea why it would affect only this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have force saved the file with CRLF line endings, which has produced a much smaller diff in GitHub.
I am guessing that this file has messed up line endings. Not sure what I can do beyond this. It's at least reviewable now, even if 90% of the changes are not really changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/AutoMapper/TypeDetails.cs
Outdated
return !property.IsStatic() && shouldMapProperty(property); | ||
case FieldInfo field: | ||
return !field.IsStatic && shouldMapField(field); | ||
case ConstructorInfo constructor: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't belong here, constructors are not members to map.
src/AutoMapper/TypeMap.cs
Outdated
var constructors = DestinationTypeToUse | ||
.GetDeclaredConstructors() | ||
.Where(ci => !ci.IsStatic); | ||
.Where(ci => !ci.IsStatic && Profile.ShouldMapCtor(ci)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should just check Constructors in TypeDetails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should have done that in the first place too 😄 I'll change it.
src/UnitTests/Bug/ShouldMapCtor.cs
Outdated
|
||
namespace AutoMapper.UnitTests.Bug | ||
{ | ||
public abstract class ShouldMapCtor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or you can simply rename the namespace from Bug to ShouldMapCtor and then this class is not useful anymore. The file should be one level up. The tests should work against the API. Either assert that some constructor is used when calling Map or assert that configuration validation fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll move it.
I wasn't comfortable with these tests, but couldn't get past the way I'd tried to work around outside of AM. Asserting the configuration validation fails, should be fine. I'll do that.
Right, we're stepping on each other's toes now. I'll leave this alone. I noticed the cosmetic changes too :) Happy to squash it down if needs be. |
@jbogard I think ShouldUseConstructor makes more sense than ShouldMapConstructor. |
Sorry about the commits :) I thought it would easier to do it myself. |
No problem. I agree with |
No, constructor mapping is only about mapping the constructor parameters from the source object. You're filtering all the constructors, regardless of constructor mapping. |
@lxalln Can you please do the rename, as I don't have VS handy? |
Will do shortly |
I was wrong, this will still allow a constructor without parameters to be used, regardless of the condition. I'd say we want it to apply to those too, but I guess it's debatable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
@lbargaoanu The tests I put in prove that an empty constructor cannot be used if it is being excluded by the filter. Am I missing something? |
If there is only the default constructor, it will be used regardless of the condition, right? |
The default constructor is returned from |
Make this test. The condition always returns false. You have only a default constructor. The mapping works. It's not unreasonable. We'l just have to see what people expect :) |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Allows for constructors to be excluded in the same way as properties
and fields (ShouldMapField & ShouldMapProperty).
Fixes #2691.