I want to ask some questions about best practices regarding mapping types and using extension methods in C#. I know this topic has been discussed multiple times over past few years, but I've read a lot of posts and still have doubts.
The problem I encountered was extending class that I own with "convert" functionality. Let's say that I have class "Person" that represents an object which will be used by some logic. I also have a class "Customer" that represents a response from external API (actually there will be more than one API, so I need to map each API's response to common type: Person). I have access to both classes' source code and theoretically can implement my own methods there. I need to convert Customer to Person so I can save it to database. The project doesn't use any automatic mappers.
I have 4 possible solutions in mind:
.ToPerson() method in Consumer class. It's simple, but it seems like breaking the Single Responsibility pattern to me, especially that the Consumer class is mapped to other classes (some required by another external API) as well, so it would need to contain multiple mapping methods.
Mapping constructor in Person class taking Consumer as an argument. Also easy and also seems like breaking Single Responsibility pattern. I'd need to have multiple mapping constructors (since there will be class from another API, providing the same data as Consumer but in slightly different format)
Converters class with extension methods. This way I can write .ToPerson() method for Consumer class and when another API is introduced with it's own NewConsumer class, I can just write another extension method and keep it all in the same file. I've heard an opinion that extension methods are evil in general and should be used only if absolutely necessary so that's what is holding me back. Otherwise I like this solution
Converter/Mapper class. I create separate class that will handle conversions and implement methods that will take source class instance as an argument and return destination class instance.
To sum up, my problem can be reduced to number of questions (all in context to what I described above):
Is putting conversion method inside (POCO?) object (like .ToPerson() method in Consumer class) considered breaking single responsibility pattern?
Is using converting constructors in (DTO-like) class considered breaking single responsibility pattern? Especially if such class can be converted from multiple source types, so multiple converting constructors would be required?
Is using extension methods while having access to original class source code considered bad practice? Can such behavior be used as viable pattern for separating logic or is it an anti-pattern?