私は現在、新しいアプリケーションを構築していて、 クリーンアーキテクチャ の原則のいくつかを適用しようとしています。私の最初の障害の1つは、独自のIdentity
システムを実装することです(AspNetCore.Identity
ライブラリとの密接な結合を回避するため)。
私の懸念の1つは、パスワードのハッシュと生成です。 AspNetCore.Identity Password Hasher と同様または同じプロセスに従うことを検討していますが、このロジックをどこで処理すればよいかよくわかりません。
私の最初の考えは、これはドメインエンティティに関係しているので、これをDomain
レイヤーに配置する必要があるということです。しかし、私はパスワードを検証するときに、これが将来頭痛の種と分散ロジックを作成することを心配しています。一方、アプリケーションレイヤーで独自のIPasswordHasher
インターフェイスを定義することもできますが、これには、アプリケーションレイヤーがハッシュと検証のスキームを指示するというマイナスの影響があります。これらのエンティティを将来別のアプリケーションと共有する場合、ハッシュアルゴリズムが同じであることを確認する必要があります。
しかし、同じことを言えば、Microsoft.AspNetCore.Identity
で既に定義されているIPasswordHasher
インターフェースを単に使用することは素晴らしいことですが、密結合はしたくありません。
では、アプリケーション/ドメインレイヤーでAspNetCoreライブラリを参照する必要なしに、ある種のハッシュロジック(AspNetCoreで定義されたPasswordHasherを使用する可能性さえある)を実装するための理想的なアプローチは何でしょうか。また、ドメインレイヤーまたはアプリケーションレイヤーで、実際にパスワードハッシュを実装する必要がありますか?
ID管理はおそらくコアの問題ドメインの一部ではないため、コアのビジネスロジックのどこにもありません。また、エンティティ(クリーンアーキテクチャの中心)は、データベースや特定のID管理システムなどの外部システムに依存しないようにする必要があります。代わりに、コアが必要とするサービスのインターフェースを定義してから、そのサービスを実装します。この実装は「アプリケーションレイヤー」と同様のレベルになりますが、クリーンアーキテクチャには特にアップダウンレイヤーがなく、インサイドアウトレイヤーのみがあることに注意してください。内部の部分は、外部で実装されるインターフェースを定義します。
コアの問題ドメインの観点から見ると、正確なID管理スキームとパスワードハッシュアルゴリズムは実際には無関係です。したがって、これらの詳細は外部サービスによって決定されることが正しいです。もちろん、そのサービスは正しく実装されない可能性があります(プレーンテキストのパスワードの保存など)が、エンティティ内のID管理も可能です。しかし、問題が発生するこの可能性は、テストを高速化するために使用できる柔軟性も意味します。安全なパスワードハッシュアルゴリズムは、設計上、かなり低速です。そのため、一部のテストでは真のID管理実装を使用したくないが、モック実装と交換したい場合があります。
「将来これらのエンティティを別のアプリケーションと共有する場合は…」–いいえ、そのような仮定は通常2つの理由で間違っています。まず、エンティティはアプリケーションの中心的なモデルです。これは通常は一意であり、再利用できません。次に、YAGNIを検討します。一部のコンポーネントを再利用する必要が生じた場合は、コードをリファクタリングして再利用できます。これは、アプリケーション開発の贅沢です。後でデザインを変更できます。対照的に、外部で使用されるライブラリーは、最初にAPI設計を正しく行う必要があります。
また、クリーンアーキテクチャの全体的な目標は、設計の決定をできる限り延期することです。そのため、依存関係は内部にのみ流れます。実際にどのように機能するかを気にすることなく、コアビジネスロジックを記述できます。外部サービスが必要な場合は、後で実装するインターフェースを定義します。どうやって?それは将来を決定するためのものです。クリーンアーキテクチャは、トップダウンの設計アプローチを意味します。 ID管理ソリューションの選択やWebフレームワークの選択(またはソフトウェアがWebアプリかデスクトップアプリかどうかの選択)のような決定は、少なくとも理論的には延期できます。これは、SICPが教えた「プログラミング ウィッシュフルシンキング 」の手法に非常に似ています。