型のマッピングとC#での拡張メソッドの使用に関するベストプラクティスについて質問したいです。このトピックは過去数年にわたって何度も議論されてきましたが、私は多くの投稿を読みましたが、まだ疑問があります。
私が遭遇した問題は、私が所有するクラスを「変換」機能で拡張することでした。あるロジックで使用されるオブジェクトを表すクラス「Person」があるとしましょう。また、外部APIからの応答を表すクラス「Customer」もあります(実際には、複数のAPIがあるため、各APIの応答を共通のタイプ:Personにマッピングする必要があります)。両方のクラスのソースコードにアクセスでき、理論的には独自のメソッドを実装できます。データベースに保存できるように、CustomerをPersonに変換する必要があります。プロジェクトは自動マッパーを使用しません。
私は4つの可能な解決策を考えています:
Consumerクラスの.ToPerson()メソッド。シンプルですが、私には単一責任パターンを壊しているように見えます。特に、Consumerクラスは他のクラス(別の外部APIに必要なもの)にもマップされるため、複数のマッピングメソッドを含める必要があります。
Consumerを引数として取るPersonクラスのコンストラクターをマッピングします。また、簡単で、単一責任パターンを壊すようにも見えます。複数のマッピングコンストラクターが必要です(別のAPIからのクラスがあり、Consumerと同じデータをわずかに異なる形式で提供するため)
拡張メソッドを持つコンバータークラス。この方法で、Consumerクラスの.ToPerson()メソッドを記述でき、独自のNewConsumerクラスで別のAPIが導入された場合、別の拡張メソッドを記述して、すべてを同じファイルに保存できます。拡張メソッドは一般的に悪であり、絶対に必要な場合にのみ使用すべきだという意見を聞いたことがあります。それ以外の場合、私はこのソリューションが好きです
Converter / Mapperクラス。変換を処理する別のクラスを作成し、ソースクラスインスタンスを引数として受け取り、宛先クラスインスタンスを返すメソッドを実装します。
要約すると、私の問題は質問の数に減らすことができます(すべて、上記で説明した内容に関連して)。
変換メソッドを(POCO?)オブジェクト(Consumerクラスの.ToPerson()メソッドなど)内に配置することは、単一の責任パターンを壊すことを考慮していますか?
(DTOのような)クラスでの変換コンストラクターの使用は、単一の責任パターンの破壊と見なされますか?特に、そのようなクラスを複数のソースタイプから変換できる場合、複数の変換コンストラクタが必要になりますか?
元のクラスのソースコードにアクセスしながら拡張メソッドを使用するのは悪い習慣と見なされていますか?このような動作は、ロジックを分離するための実行可能なパターンとして使用できますか、それともアンチパターンですか?
Person
クラスはDTO?動作が含まれていますか?