{"action":"created","issue":{"url":"https://api.github.com/repos/JoshClose/CsvHelper/issues/821","repository_url":"https://api.github.com/repos/JoshClose/CsvHelper","labels_url":"https://api.github.com/repos/JoshClose/CsvHelper/issues/821/labels{/name}","comments_url":"https://api.github.com/repos/JoshClose/CsvHelper/issues/821/comments","events_url":"https://api.github.com/repos/JoshClose/CsvHelper/issues/821/events","html_url":"https://github.com/JoshClose/CsvHelper/issues/821","id":269767997,"number":821,"title":"Custom Expressions","user":{"login":"ajorkowski","id":1185777,"avatar_url":"https://avatars3.githubusercontent.com/u/1185777?v=4","gravatar_id":"","url":"https://api.github.com/users/ajorkowski","html_url":"https://github.com/ajorkowski","followers_url":"https://api.github.com/users/ajorkowski/followers","following_url":"https://api.github.com/users/ajorkowski/following{/other_user}","gists_url":"https://api.github.com/users/ajorkowski/gists{/gist_id}","starred_url":"https://api.github.com/users/ajorkowski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ajorkowski/subscriptions","organizations_url":"https://api.github.com/users/ajorkowski/orgs","repos_url":"https://api.github.com/users/ajorkowski/repos","events_url":"https://api.github.com/users/ajorkowski/events{/privacy}","received_events_url":"https://api.github.com/users/ajorkowski/received_events","type":"User","site_admin":false},"labels":[{"id":28497476,"url":"https://api.github.com/repos/JoshClose/CsvHelper/labels/feature","name":"feature","color":"02e10c","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":11,"created_at":"2017-10-30T21:57:38Z","updated_at":"2017-11-08T19:53:56Z","closed_at":"2017-11-02T02:50:25Z","author_association":"CONTRIBUTOR","body":"Unfortunately with the upgrade to 3/4 of CsvHelper, the internals have changed enough so that it is pretty much impossible to do custom expression work.\r\n\r\nHere is my example (and maybe there is a cleaner way to deal with this) - I have IEnumerables (of objects) in my data and to make them come out nicely in the csv I use a custom attribute to specify how many copies of the items I want. So for example if I had an object with two properties (Name/Code) and the attribute has a count of 4, then I will output 8 fields in total (with headers and everything).\r\n\r\nHow I went about implementing it before is in two areas:\r\n\r\n1) Create a custom class map, and during the automap phase if I detect the attribute then instead of creating an IEnumerableConverter, I instead just create N reference maps equal to the loop amount (using a custom class map to track the index), and the reference map uses the type definition of the IEnumerable. We also add some prefixing here so that the output will have some indexes in the headers.\r\n\r\n2) If I just use the above then of course I will get an error during the mapping, since the reference map would be trying to map members on top of the IEnumerable<T> (not just T itself), so the second step was to overwrite the expression code to add in something like {IEnumerable<T>}[index] in the expression, so that the members would be accessing from the right type.\r\n\r\nI managed to make the relevant changes in v4, however I have a problem with actually being able to use my overwritten `ExpressionManager` class. There are a large number of nested classes that makes it basically impossible to inject the custom class:\r\n\r\n`ExpressionManager` -> `ObjectRecordWriter` (built in constructor of RecordWriter) -> `RecordWriterFactory` (built in factory method) -> `RecordManager` (built in constructor) -> `CsvWriter` (built in constructor).\r\n\r\nApart from the objects being built in the constructor (so you can't change the implementation), the `RecordWriterFactory.MakeRecordWriter<T>` method is not virtual so again not possible to change the implementation.\r\n\r\nPerhaps there are enough 'components' that it would be worth inverting all the dependencies and building a central container - that way it is easier for someone like me to replace components easily? I've already spent the time in my code updating this, so I would really prefer to not have to roll back my csvhelper version... I might try pushing up a PR with a possible implementation."},"comment":{"url":"https://api.github.com/repos/JoshClose/CsvHelper/issues/comments/342939334","html_url":"https://github.com/JoshClose/CsvHelper/issues/821#issuecomment-342939334","issue_url":"https://api.github.com/repos/JoshClose/CsvHelper/issues/821","id":342939334,"user":{"login":"JoshClose","id":114971,"avatar_url":"https://avatars3.githubusercontent.com/u/114971?v=4","gravatar_id":"","url":"https://api.github.com/users/JoshClose","html_url":"https://github.com/JoshClose","followers_url":"https://api.github.com/users/JoshClose/followers","following_url":"https://api.github.com/users/JoshClose/following{/other_user}","gists_url":"https://api.github.com/users/JoshClose/gists{/gist_id}","starred_url":"https://api.github.com/users/JoshClose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JoshClose/subscriptions","organizations_url":"https://api.github.com/users/JoshClose/orgs","repos_url":"https://api.github.com/users/JoshClose/repos","events_url":"https://api.github.com/users/JoshClose/events{/privacy}","received_events_url":"https://api.github.com/users/JoshClose/received_events","type":"User","site_admin":false},"created_at":"2017-11-08T19:53:56Z","updated_at":"2017-11-08T19:53:56Z","author_association":"OWNER","body":"6.0.0 is on NuGet."}}
{"actor":{"display_login":"JoshClose"}}