0

I'm new to AutoMapper, I want to post this issue on their github, but considering their issue template:

If you're new to AutoMapper, please ask a question on StackOverflow first and come back here if the people there consider it a bug.

I have to post here.

To simplify the problem, I removed unnecessary code as much as possible.

class Rule {
    public ReadOnlyCollection<string>? Collection { get; set; }
}

var config = new MapperConfiguration(c => {
    c.CreateMap<Rule, Rule>();
});
config.AssertConfigurationIsValid();

var mapper = config.CreateMapper();

var source = new Rule {
    Collection = Array.AsReadOnly(new [] { "a", "b", "c" })
};
var destination = new Rule();

// The following line throw an exception: 
// ArgumentException: System.Collections.ObjectModel.ReadOnlyCollection`1[System.String] 
// needs to have a constructor with 0 args or only optional args.
// Validate your configuration for details.
mapper.Map(source, destination); 

And docs said:

When calling Map with an existing readonly collection, such as IEnumerable<>, the setter will be used to replace it. If you actually have to map into that collection, you need to change its type to a writable collection, such as List<>, HashSet<>, ICollection<>, IList<> or IList. Alternatively, you can remove the setter or set UseDestinationValue.

But the exception seems tell me mapper is going to do a deep clone rather than the setter will be used to replace it.

AutoMapper version: 11.0.1

enter image description here

huang
  • 919
  • 11
  • 22
  • What's your `x`? How does the source init looks exactly? It could be, that your x does not have a matching/needed constructor. – keenthinker Feb 19 '22 at 17:06
  • x is c# string. Why need parameterless constructor? I just want to do `destination.Collection = source.Collection` operation while mapping. – huang Feb 19 '22 at 17:09
  • Ok. Can you show the complete line/code with for example two parameters (string) only for the source collection init (so that your example compiles)? Looking at the docs for the constructor of `ReadOnlyCollection`, it does not have something matching the pseudo code. – keenthinker Feb 19 '22 at 17:19
  • 1
    Why is it that when you ask questions on stackoverflow, there are always irrelevant nitpicky requirements? – huang Feb 19 '22 at 17:25
  • source, destination both are existing objects, why AutoMapper trying to construct the property of them? If not why AutoMapper care what constructor of `ReadOnlyCollection`? – huang Feb 19 '22 at 17:27
  • 1
    I just wanted to have a complete example to try to reproduce your problem and analyze it and try to answer your question. If you are not ready support the people trying to help, then don't ask in the first place. – keenthinker Feb 19 '22 at 17:27
  • Do you not understand pseudocode? Do you want me to submit the entire project of several hundred MB for you to compile successfully? StupidOverflow. – huang Feb 19 '22 at 17:28
  • 1
    @JokeHuang Please [edit] your question to include a [mcve], which generate the exception you mention. When I run your code no exception is thrown and the `Map()` method is updating the `destination` instance. – Progman Feb 19 '22 at 19:19

1 Answers1

0

I'm sorry for my recklessness.

In fact, the Rule class has more than one ReadOnlyCollection<string>? property:

class Rule {
    public ReadOnlyCollection<string>? CollectionA { get; set; }
    public ReadOnlyCollection<string>? CollectionB { get; set; }
}

So, the following code as my origin question never initialize the CollectionB:

var source = new Rule {
    CollectionA = Array.AsReadOnly(new [] { "a", "b", "c" })
};
var destination = new Rule();

mapper.Map(source, destination); 

It cause the null issue of AutoMapper, the solution is append ForAllMembers(o => o.AllowNull()) when CreateMap

var config = new MapperConfiguration(c => {
    c.CreateMap<Rule, Rule>().ForAllMembers(o => o.AllowNull());
});

SORRY, EVERYONE!!!

huang
  • 919
  • 11
  • 22