ConfigurationException: 'Types that inherit IEnumerable cannot be auto mapped' when using custom class based on DynamicObject (NOT ExpandoObject) which also implements IDictionary
eduarddejong opened this issue · comments
Describe the bug
Others have reported issues with this exception in the past, but as far as I can see it where all different situations, and what I am doing here is a bit more specific, and that is that I am using my own implementation based on the abstract class DynamicObject
, which works pretty much the same as ExpandoObject
, but you make your own implementation instead.
My implementation is as follows:
internal sealed class MyDynamicObject : DynamicObject, IDictionary<string, object?>, INotifyPropertyChanged
{
// (implementation details)
}
The problem:
IDictionary<TKey,TValue>
is based on IEnumerable<KeyValuePair<TKey,TValue>>
and the CsvWriter
does not like this, and throws the exception mentioned in the subject.
I am just trying to export CSV file from a list of objects of my class, using CsvWriter.WriteRecordsAsync
.
When I remove IDictionary<string, object?>
from my class, it suddenly works, without modifying internal details of my class. CsvWriter.WriteRecordsAsync
does not throw an exception anymore.
However, my application depends on this implementation, as it relies on Dictionary behaviour as well with keys and values from my class (I internally use a dictionary).
So I am breaking my code if I remove it.
Why can't I just use ExpandoObject
instead?
My class also has a couple of non-dynamic (real) properties and some custom behaviour.
ExpandoObject
is also sealed so we cannot derive from that one.
To Reproduce
See above.
Expected behavior
DynamicObject should be supported, and even if it implements IEnumerable (either directly or indirectly such as via IDictionary).
I already found the solution! :
Turns out it actually works without any problem. I needed to cast my object to dynamic
in order to make it work with CsvWriter.
And this does not only apply to DynamicObject
, but also to ExpandoObject
.
I wasn't aware of this.
Were you using it as a dynamic object? Meaning
dynamic o = new ExpandoObject();
Oh, whoops. I see now that it's only picking up the dynamic properties of my DynamicObject implementation, and not the other properties. But it's not such a problem.
I can still create an ExpandoObject and copy all the properties, I have already written some code in that direction inside a LINQ Select construct.
I realize I probably already want to do that because I also have custom column names which I need as CSV header as well.
Were you using it as a dynamic object? Meaning
dynamic o = new ExpandoObject();
Thanks for your reply! I am actually doing as dynamic
now in my Select and that also works, which works effectively the same (I do not add the dynamic properties using dot notation, I fill it dynamically like dictionary. That's why I also didn't need to use the dynamic keyword initially).