むンスタントデザむン

人々はJava甚に曞かれた叀い本から建築を孊びたす。 これらの本は優れおいたすが、圓時の楜噚を䜿甚しお、圓時の問題を解決しおいたす。 時間は倉わり、CはJavaよりも軜いScalaに䌌おおり、新しい優れた本はほずんどありたせん。

この蚘事では、良いコヌドず悪いコヌドの基準、枬定方法ず枬定察象を調べたす。 兞型的なタスクずアプロヌチの抂芁を芋お、長所ず短所を分析したす。 最埌に、Webアプリケヌションを蚭蚈するための掚奚事項ずベストプラクティスがありたす。

この蚘事は、DotNext 2018モスクワ䌚議からの私のレポヌトの転写です。 テキストに加えお、ビデオずカットの䞋のスラむドぞのリンクがありたす。



サむトの スラむドずレポヌトペヌゞ 。
私に぀いお簡単に説明するず、私はカザン出身で、ハむテクグルヌプで働いおいたす。 私たちはビゞネス向けの゜フトりェアを開発しおいたす。 最近、私は䌁業゜フトりェア開発ず呌ばれるカザン連邊倧孊でコヌスを教えおいたす。 時々、゚ンゞニアリングの実践、゚ンタヌプラむズ゜フトりェアの開発に関するHabrに関する蚘事を執筆しおいたす。

ご想像のずおり、今日ぱンタヌプラむズ゜フトりェアの開発、぀たり最新のWebアプリケヌションの構築方法に぀いお説明したす。


基準


基準を策定したす。 デザむンに぀いお話すのが「私のカンフヌはあなたのカンフヌより匷い」ずいうスタむルの話をするずき、私は本圓にそれが奜きではありたせん。 ビゞネスには、原則ずしお、お金ず呌ばれる特定の基準がありたす。 時は金なりずいうこずは誰もが知っおいるので、これらの2぀のコンポヌネントが最も重芁です。



だから、基準。 原則ずしお、䌁業は「単䜍時間あたりできるだけ倚くの機胜」を芁求するこずが最も倚くありたすが、1぀の泚意事項がありたす。これらの機胜は機胜するはずです。 そしお、それが壊れる可胜性のある最初のステップはコヌドレビュヌです。 ぀たり、プログラマヌは「3時間以内にやる」ず蚀ったようです。 3時間が経過するず、レビュヌがコヌドに反映され、チヌムリヌダヌは「ああ、いいえ、やり盎しおください」ず蚀いたした。 さらに3぀ありたす。コヌドレビュヌで合栌した反埩の数ですので、3時間を掛ける必芁がありたす。

次のポむントは、受け入れテストの段階からの戻りです。 同じこず。 この機胜が機胜しない堎合は、機胜したせん。これらの3時間は1週間、2分間-よくあるこずです。 最埌の基準は、回垰ずバグの数ですが、それでもテストず受け入れにもかかわらず、実皌働を経たした。 これも非垞に悪いです。 この基準には1぀の問題がありたす。 リポゞトリに䜕かをプッシュするずいう事実ず、2週間埌に䜕かが壊れたずいう事実ずの関係を远跡するのは難しいため、远跡するのは困難です。 ただし、それでも可胜です。

アヌキテクチャ開発


むかしむかし、プログラマヌがプログラムを曞き始めたばかりだったずき、ただアヌキテクチャはなく、誰もが奜きなこずをすべおやりたした。



したがっお、私たちはそのような建築スタむルを埗たした。 ここでは「ヌヌドルコヌド」ず呌ばれ、海倖では「スパゲッティコヌド」ず蚀いたす。 すべおがすべおず結び぀いおいたす。ポむントAで䜕かを倉えおいたす-ポむントBで壊れたす。䜕が䜕ず結び぀いおいるのかを理解するこずは完党に䞍可胜です。 圓然、プログラマはこれが機胜しないこずをすぐに認識し、いく぀かの構造を䜜成する必芁があり、いく぀かのレむダヌが圹立぀ず刀断したした。 さお、ミンスミヌトがコヌドであり、ラザニアがそのようなレむダヌであるず想像するなら、ここにレむダヌドアヌキテクチャの図を瀺したす。 ひき肉は现かく刻たれたたたですが、今ではレむダヌ1のひき肉はそれを取り蟌んでレむダヌ2のひき肉ず話をするこずはできたせん。コヌドに䜕らかの圢を䞎えたした写真でさえ、登山がより枠組されおいるこずがわかりたす。



おそらく誰もが叀兞的な階局化アヌキテクチャに粟通しおいるでしょう。UI、ビゞネスロゞック、デヌタアクセスレむダがありたす。 䌚瀟を蟞めた建築家にちなんで名付けられたあらゆる皮類のサヌビス、ファサヌド、レむダヌがただありたすが、それらの数に制限はありたせん。



次の段階は、いわゆるタマネギのアヌキテクチャでした。 倧きな違いがあるように思われたす。その前に小さな正方圢があり、ここに円がありたした。 たったく違うようです。



そうでもない。 党䜓的な違いは、その時点でSOLIDの原則が定匏化されたこずであり、叀兞的なタマネギでは、䜕らかの理由で抜象ドメむンコヌドが実装、デヌタアクセスに䟝存するため、䟝存関係の逆転に問題があるこずが刀明したため、デヌタアクセスを展開するこずにしたした、およびデヌタアクセスがドメむンに䟝存するようにしたす。



ここで私はドロヌむングを緎習し、タマネギのアヌキテクチャを描きたしたが、叀兞的な「リング」ではありたせん。 倚角圢ず円の間に䜕かを埗たした。 これは、「タマネギ」、「六角圢」、たたは「ポヌトずアダプタヌ」ずいう蚀葉に出䌚った堎合、それがすべお同じであるこずを瀺すためだけに行いたした。 ポむントは、ドメむンが䞭心にあり、サヌビスにラップされおいるこずです。必芁に応じお、ドメむンたたはアプリケヌションサヌビスにするこずができたす。 そしお、DALが移動したUI、テスト、むンフラストラクチャの圢の倖の䞖界-圌らはこのサヌビス局を通しおドメむンず通信したす。

簡単な䟋。 メヌル曎新


このようなパラダむムで、ナヌザヌのメヌルアドレスを曎新するずいう単玔なナヌスケヌスがどのように芋えるかを芋おみたしょう。



リク゚ストを送信し、怜蚌し、デヌタベヌスの倀を曎新し、新しいメヌルに通知を送信する必芁がありたす。「すべおが正垞であり、メヌルを倉曎したした。すべお問題ありたせん」、「200」ブラりザに返信したす。



コヌドは次のようになりたす。 ここには、暙準のASP.NET MVC怜蚌があり、デヌタを読み取り、曎新するORMがあり、通知を送信する䜕らかの電子メヌル送信者がいたす。 すべおが良いようですね。 1぀の泚意点-理想的な䞖界で。

珟実の䞖界では、状況はわずかに異なりたす。 ポむントは、承認、゚ラヌチェック、フォヌマット、ログ、およびプロファむリングを远加するこずです。 これはすべお、ナヌスケヌスずは関係ありたせんが、すべおそうでなければなりたせん。 そしお、その小さなコヌドは倧きくお恐ろしいものになりたした。ネストが倚く、コヌドが倚く、読み取りが難しく、最も重芁なこずは、ドメむンコヌドよりもむンフラストラクチャコヌドの方が倚いずいう事実です。



「サヌビスはどこですか」ずあなたは蚀いたす。 すべおのロゞックをコントロヌラヌに曞き蟌みたした。 もちろん、これは問題です。今はサヌビスを远加したすが、すべお問題ありたせん。



サヌビスを远加するず、本圓に良くなりたす。倧きな足垃の代わりに、小さな矎しいラむンが1぀あるからです。

良くなっおいたすか なっおいたす そしお、このメ゜ッドを異なるコントロヌラヌで再利甚できるようになりたした。 結果は明らかです。 このメ゜ッドの実装を芋おみたしょう。



しかし、ここではすべおがそれほど良くありたせん。 このコヌドはただここにありたす。 すべおを同じようにサヌビスに移したした。 問題を解決するのではなく、単にそれを停装しお別の堎所に転送するこずにしたした。 以䞊です。



これに加えお、いく぀かの他の質問が発生したす。 コントロヌラヌたたはここで怜蚌を行う必芁がありたすか たあ、コントロヌラヌのようなものです。 たた、デヌタベヌスにアクセスしお、そのようなIDがあるかどうか、たたはそのような電子メヌルを持぀他のナヌザヌがいないこずを確認する必芁がある堎合はどうでしょうか。 うヌん、それではサヌビスで。 しかし、ここでの゚ラヌ凊理は この゚ラヌ凊理はおそらくここにあり、コントロヌラヌのブラりザヌに応答する゚ラヌ凊理です。 SaveChangesメ゜ッドは、サヌビス内にありたすか、それをコントロヌラヌに転送する必芁がありたすか 1぀のサヌビスが呌び出された堎合、そのサヌビスを呌び出す方が論理的であり、コントロヌラヌ内に呌び出す必芁のある3぀のサヌビスメ゜ッドがある堎合、これらのサヌビスの倖郚で呌び出しおトランザクションが1぀になるようにする必芁があるためです これらの反射は、おそらくレむダヌが問題を解決しないこずを瀺唆しおいたす。



そしお、この考えは耇数の人に起こりたした。 Googleを䜿甚する堎合、これらの立掟な倫のうち少なくずも3人が同じこずに぀いお曞いおいたす。 䞊から䞋ぞ シンプルむンゞェクタヌ IoCコンテナヌの䜜成者であるStephen .NET Junkie残念ながら、圌はむンタヌネット䞊のどこにも衚瀺されないため、圌の姓を知りたせん。 次のゞミヌ・ボガヌドはAutoMapperの著者です。 そしお、䞋にあるのは、楜しみず利益のためにFの著者であるScott Vlashinです。



これらすべおの人々は同じこずに぀いお話し、局に基づいおではなく、ナヌスケヌス、぀たりビゞネスが私たちに求めおいる芁件に基づいおアプリケヌションを構築するこずを提案したす。 したがっお、Cのナヌスケヌスは、IHandlerむンタヌフェむスを䜿甚しお決定できたす。 入力倀があり、出力倀があり、このナヌスケヌスを実際に実行するメ゜ッド自䜓がありたす。



そしお、このメ゜ッドの内郚には、ドメむンモデル、たたは読み取り甚の非正芏化モデルがありたす。䜕かを探す必芁がある堎合、DapperたたはElastic Searchを䜿甚できたす。 -ストアドプロシヌゞャを備えたシステム-問題なく、ネットワヌク芁求も-䞀般に、そこに必芁なものはすべおありたす。 しかし、レむダヌがない堎合はどうすればいいですか



開始するには、UserServiceを削陀したしょう。 メ゜ッドを削陀しおクラスを䜜成したす。 そしお削陀し、再床削陀したす。 そしお、クラスを取埗しお削陀したす。



考えおみたしょう、これらのクラスは同等ですか GetUserクラスはデヌタを返し、サヌバヌ䞊の䜕も倉曎したせん。 これは、たずえば、「Give me the user ID」ずいうリク゚ストに関するものです。 UpdateEmailおよびBanUserクラスは、操䜜の結果を返し、状態を倉曎したす。 たずえば、サヌバヌに「状態を倉曎しおください。䜕かを倉曎する必芁がありたす」ず䌝えた堎合。



HTTPプロトコルを芋おみたしょう。 HTTPプロトコルの仕様に埓っお、サヌバヌの状態を倉曎せずにデヌタを返すGETメ゜ッドがありたす。



たた、サヌバヌの状態を倉曎し、操䜜の結果を返すこずができる他のメ゜ッドがありたす。



CQRSパラダむムは、HTTPプロトコル甚に特別に蚭蚈されおいるようです。 ク゚リはGET操䜜であり、コマンドはPUT、POST、DELETEです。䜕も発明する必芁はありたせん。



ハンドラを再定矩し、远加のむンタヌフェむスを定矩したす。 IQueryHandlerは、入力倀のタむプがIQueryであるずいう制玄を掛けたずいう点でのみ異なりたす。 IQueryはマヌカヌむンタヌフェむスであり、このゞェネリックのみです。 QueryHandlerに制玄を蚭定するにはゞェネリックが必芁です。QueryHandlerを宣蚀するず、QueryではなくQueryオブゞェクトを枡すこずができたすが、Queryオブゞェクトをそこに枡すず、その戻り倀がわかりたす。 これは、むンタヌフェむスが1぀しかない堎合に䟿利です。そのため、コヌド内で実装を探す必芁がなく、たた混乱しないようにする必芁がありたす。 IQueryHandlerを蚘述し、そこで実装を蚘述したす。TOutでは、別のタむプの戻り倀に眮き換えるこずはできたせん。 コンパむルしたせん。 したがっお、どの入力倀がどの入力デヌタに察応するかをすぐに確認できたす。



CommandHandlerの状況は1぀䟋倖がありたすが、このゞェネリックはもう1぀のトリックに必芁です。これに぀いおはもう少し詳しく芋おいきたす。

ハンドラヌの実装


ハンドラヌ、私たちが発衚した、それらの実装は䜕ですか



問題はありたすか 䜕かが倱敗したようです。

デコレヌタは救助に急ぎたす


しかし、それは圹に立たなかった。ただ道の真っin䞭にいるので、もう少しファむナラむズする必芁があり、今回はデコレヌタヌパタヌン、぀たりその玠晎らしいレむアりト機胜を䜿甚する必芁がある。 デコレヌタは、デコレヌタに包たれたり、デコレヌタに包たれたり、デコレヌタに包たれたりしたす。退屈するたで続けおください。



次に、すべおが次のようになりたす。入力Dtoがあり、最初のデコレヌタ、2番目、3番目に入り、ハンドラに移動しお終了し、すべおのデコレヌタを通過しお、ブラりザでDtoを返したす。 埌で継承するために抜象基本クラスを宣蚀し、Handlerの本䜓をコンストラクタヌに枡し、远加のデコレヌタヌロゞックがハングする抜象Handleメ゜ッドを宣蚀したす。



これで、デコレヌタの助けを借りお、パむプラむン党䜓を構築できたす。 チヌムから始めたしょう。 䜕があったの 入力倀、怜蚌、アクセス制埡、ロゞック自䜓、このロゞックの結果ずしお発生するいく぀かのむベント、および戻り倀。



怜蚌から始めたしょう。 デコレヌタを宣蚀したす。 これらのすべおを実行し、怜蚌が倱敗し、戻り倀の型がIEnumerable<validationresult>であるかどうかを確認しおから、型が䞀臎するため返すこずができたす。 そしお、それが他のハンドラヌである堎合は、䟋倖をスロヌする必芁がありたす。ここには結果がなく、別の戻り倀の型がありたす。



次のステップはセキュリティです。 たた、デコレヌタを宣蚀し、CheckPermissionメ゜ッドを䜜成しお怜蚌したす。 突然䜕かがうたくいかなかった堎合、それだけです、続行したせん。 これで、すべおのチェックを完了し、すべおが正垞であるこずを確認した埌、ロゞックを実行できたす。

プリミティブぞの執着


ロゞックの実装を瀺す前に、少し前に、぀たりそこに来る入力倀から始めたいず思いたす。



さお、このようなクラスを遞択するず、ほずんどの堎合、このようになりたす。 少なくずも私が日垞業務で目にするコヌド。



怜蚌が機胜するように、怜蚌の皮類を瀺すいく぀かの属性をここに远加したす。 これはデヌタ構造の面では圹立ちたすが、デヌタベヌスの倀をチェックするなどの怜蚌には圹立ちたせん。 それは単なるEmailAddressであり、デヌタベヌスに移動するためにこれらの属性をどのように䜿甚するかを確認する方法、堎所は明確ではありたせん。 属性の代わりに、特別なタむプに切り替えるず、この問題は解決したす。



intプリミティブの代わりに、intキヌを持぀特定の゚ンティティであるゞェネリックを持぀Id型を宣蚀したす。 そしお、この゚ンティティをコンストラクタに枡すか、そのIDを枡したすが、同時に、Idが取埗しお返すこずができる関数を枡す必芁がありたす。



電子メヌルでも同じこずを行いたす。 すべおが同じように芋えるように、すべおのメヌルを最終行に倉換したす。 次に、Email属性を取埗し、ASP.NET怜蚌ずの互換性のために静的ずしお宣蚀し、ここでは単にそれを呌び出したす。 ぀たり、これも実行できたす。 ASP.NETむンフラストラクチャでこれらすべおをキャッチするには、シリアル化やModelBindingをわずかに倉曎する必芁がありたす。 そこには倚くのコヌドはありたせん。それは比范的単玔なので、そこで止たりたせん。



これらの倉曎埌、プリミティブ型ではなく、特殊な型がここに衚瀺されたすIdおよびEmail。 そしお、これらのModelBinderず曎新されたデシリアラむザが機胜した埌、これらの倀が正しいこずを確実に知るこずができたす。そのような倀がデヌタベヌスにあるこずも含たれたす。 「䞍倉匏」



次に説明するポむントは、クラス内の䞍倉条件の状態です。これは、倚くの堎合、クラス、倚くのゲッタヌセッタヌのみが存圚する貧血モデルが䜿甚されるためです。 耇雑なビゞネスロゞックを扱うため、コヌドが自己文曞化されおいるこずが重芁です。 代わりに、ORMの空ず共に実際のコンストラクタを宣蚀するこずをお勧めしたす。アプリケヌションコヌド内のプログラマがそれを呌び出せないように保護されおいるず宣蚀できたす。 ここでは、プリミティブ型ではなく、電子メヌル型を枡したす。それは既に正しく正しいものです。nullの堎合、䟋倖をスロヌしたす。 いく぀かのFody、PostSharpを䜿甚できたすが、C8がたもなく登堎するため、Null䞍可の参照型が存圚するため、蚀語でのサポヌトを埅぀こずをお勧めしたす。 次の瞬間、名前ず姓を倉曎したい堎合、おそらくそれらを䞀緒に倉曎したいので、それらを䞀緒に倉曎する適切なパブリックメ゜ッドが必芁です。



このパブリックメ゜ッドでは、これらの行の長さがデヌタベヌスで䜿甚するものず䞀臎するこずも確認したす。 そしお、䜕かが間違っおいる堎合、実行を停止したす。 ここでは、同じトリックを䜿甚したす。 特別な属性を宣蚀し、アプリケヌションコヌドで呌び出したす。



さらに、そのような属性はDtoで再利甚できたす。 さお、名前ず姓を倉曎したい堎合、そのような倉曎コマンドがありたす。 ここに特別なコンストラクタを远加する䟡倀はありたすか それは䟡倀があるようです。 それは良くなり、誰もこれらの倀を倉曎せず、それらを壊さず、正確になりたす。



実際にはそうではありたせん。 実際、Dtoは実際にはオブゞェクトではありたせん。 これは、逆シリアル化されたデヌタを栌玍する蟞曞です。 ぀たり、オブゞェクトのふりをするこずはもちろんですが、責任は1぀だけです。それは、シリアル化ず非シリアル化です。 この構造に察凊しようずするず、デザむナヌずModelBinderの発衚を開始したす。このようなこずは非垞に面倒で、最も重芁なこずは、新しいフレヌムワヌクの新しいリリヌスで䞭断したす。 これはすべお、マヌクサむモンによる蚘事「プログラムの境界はオブゞェクト指向ではありたせん」でよく説明されおいたす。興味深い堎合は、圌の投皿を読むほうが良いでしょう。そこで詳しく説明されおいたす。



぀たり、ダヌティな倖郚䞖界があり、入力にチェックを入れ、クリヌンなモデルに倉換しおから、すべおをシリアル化、ブラりザ、ダヌティな倖郚䞖界に戻したす。

ハンドラヌ


これらの倉曎がすべお行われた埌、Handerはどのように衚瀺されたすか



ここでは、読みやすくするために2行を曞きたしたが、䞀般的には1行で曞くこずができたす。 型システムがあり、怜蚌があるため、デヌタは正確です。぀たり、デヌタは鉄筋コンクリヌトであり、再床チェックする必芁はありたせん。 そのようなナヌザヌも存圚し、そのような忙しい電子メヌルを持぀他のナヌザヌはいたせん、すべおを行うこずができたす。 ただし、SaveChangesメ゜ッドぞの呌び出しはなく、通知もありたせんし、ログずプロファむラヌもありたせんよね 先に進みたす。

むベント


ドメむンむベント。



おそらく、この抂念が圌の投皿「ドメむンむベント-救い」でりディダハンによっお広たったのは初めおでしょう。 そこで圌は、Raiseメ゜ッドを䜿甚しお静的クラスを宣蚀し、そのようなむベントをスロヌするこずを提案しおいたす。 少し埌に、ゞミヌボガヌドは「A better domain events pattern」ず呌ばれるより良い実装を提案したした。



Bogardのシリアル化を1぀の小さな倉曎で瀺したすが、重芁です。 むベントをスロヌする代わりに、リストを宣蚀できたす。たた、䜕らかの反応が発生する堎所で、これらのむベントを保存する゚ンティティ内で盎接宣蚀できたす。 この堎合、このemail getterはUserクラスでもあり、このクラスはこのプロパティがgetterおよびsetterを持぀プロパティのふりをするのではなく、実際にこれに䜕かを远加したす。 ぀たり、これは冒encapsulationではなく、実際のカプセル化です。 倉曎するずき、電子メヌルが異なるこずを確認し、むベントをスロヌしたす。 このむベントはただどこにも到達しおおらず、゚ンティティの内郚リストにのみ含たれおいたす。



さらに、SaveChangesメ゜ッドを呌び出す時点で、ChangeTrackerを䜿甚し、ドメむンむベントがあるかどうかにかかわらず、むンタヌフェむスを実装する゚ンティティがあるかどうかを確認したす。 そしお、もしあれば、これらすべおのドメむンむベントを取埗し、それらをどう凊理するかを知っおいるディスパッチャに送信したしょう。

このディスパッチャの実装は別の議論のトピックであり、Cでの耇数のディスパッチにはいく぀かの困難がありたすが、これも行われおいたす。 このアプロヌチには、別の非自明な利点がありたす。 2人の開発者がいる堎合、1人はこの電子メヌルを倉曎するコヌドを蚘述でき、もう1人は通知モゞュヌルを䜜成できたす。 それらは絶察に盞互に接続されおおらず、異なるコヌドを蚘述し、1぀のDtoクラスのこのドメむンむベントのレベルでのみ接続されおいたす。 最初の開発者はある時点でこのクラスを単に砎棄し、2番目の開発者はそれに反応し、通垞発生するナヌザヌ蚭定を考慮しお、電子メヌル、SMS、電話ぞのプッシュ通知、およびその他すべおの100䞇件の通知で送信する必芁があるこずを認識しおいたす。



これが最小ですが重芁なポむントです。 Jimmyの蚘事ではSaveChangesメ゜ッドのオヌバヌロヌドを䜿甚しおいたすが、そうしないのが最善です。 たた、SaveChangesメ゜ッドをオヌバヌロヌドし、HandlerにdbContextが必芁な堎合は、埪環䟝存関係を取埗するため、デコレヌタヌで実行する方が適切です。 これで䜜業できたすが、゜リュヌションは少し䟿利でなく、少し矎しくありたせん。 したがっお、パむプラむンがデコレヌタ䞊に構築されおいる堎合、それを別に行う理由はありたせん。

ロギングずプロファむリング




コヌドのネストは残りたしたが、最初の䟋では、最初にMiniProfilerを䜿甚し、次にcatchを詊し、次にifを詊したした。 合蚈で3぀のレベルのネストがありたしたが、このレベルのネストはそれぞれ独自のデコレヌタヌにありたす。 そしお、プロファむリングを担圓するデコレヌタヌの内郚には、ネストのレベルが1぀しかないため、コヌドは完党に読み取られたす。 さらに、これらのデコレヌタヌには1぀の責任しかないこずは明らかです。 デコレヌタがロギングを担圓しおいる堎合、プロファむリングの堎合、プロファむルのみの堎合、他のすべおが他の堎所にある堎合にのみログに蚘録したす。

応答


パむプラむン党䜓が機胜した埌、Dtoを取埗しおブラりザヌにさらに送信し、JSONをシリアル化するこずしかできたせん。



しかし、もう1぀小さなこずがありたす。このようなこずは時々忘れられたす。すべおの段階で䟋倖が発生する可胜性があり、実際には䜕らかの方法でそれらを凊理する必芁がありたす。



Scott Vlashinず圌のレポヌト「鉄道指向プログラミング」に再び蚀及するしかありたせん。 なんで 元のレポヌトは、F蚀語での゚ラヌの凊理、フロヌをわずかに異なる方法で敎理する方法、およびException'ovを䜿甚するよりもこのようなアプロヌチが望たしい理由を完党に扱っおいたす。 Fでは関数型蚀語であり、スコットは関数型蚀語の機胜を䜿甚するため、これは非垞にうたく機胜したす。



おそらく、ほずんどの人はただCで​​曞いおいるので、Cでアナログを曞くず、このアプロヌチは次のようになりたす。 䟋倖をスロヌする代わりに、成功したブランチず倱敗したブランチを持぀クラスResultを宣蚀したす。 したがっお、2人のデザむナヌ。 クラスは1぀の状態のみになりたす。 このクラスは、ナニオン型の特殊なケヌスであり、Fから識別されたナニオンですが、Cには組み蟌たれおいないため、Cで曞き盎されたす。



コヌド内で誰かがnullをチェックしない可胜性があるこずをパブリックgetterを宣蚀する代わりに、パタヌンマッチングが䜿甚されたす。 繰り返しになりたすが、Fでは組み蟌みのパタヌンマッチング蚀語になりたす。Cでは、操䜜の成功結果をどう凊理するか、チェヌンをさらに䞋に倉換する方法、および゚ラヌのある関数を1぀の関数に枡す別のメ゜ッドを蚘述する必芁がありたす。 ぀たり、どのブランチが機胜しおいたかに関係なく、これを1぀の返された結果にキャストする必芁がありたす。 Fでは、これは非垞にうたく機胜したす。これは、機胜的な構成が存圚するためです。 .NETでは、耇数の結果が埗られるずすぐにこれは少し悪くなりたすが、倚くの-そしおほずんどすべおのメ゜ッドが䜕らかの理由で倱敗する可胜性がありたす-結果の関数型のほずんどすべおが結果型になり、それらを必芁ずしたす䜕かを組み合わせるために。



それらを組み合わせる最も簡単な方法はLINQを䜿甚するこずです。実際、LINQはIEnumerableだけでなく、SelectManyメ゜ッドずSelectメ゜ッドを正しい方法で再定矩するず、Cコンパむラヌはこれらの型にLINQ構文を䜿甚できるこずがわかりたす。 䞀般に、Haskell do-notationを䜿甚したトレヌシングペヌパヌか、Fの同じ蚈算匏を䜿甚したトレヌシングペヌパヌが䜜成されたす。 これはどのように読むべきですか ここに、操䜜の3぀の結果がありたす。3぀すべおのケヌスで問題がなければ、これらの結果r1 + r2 + r3を取埗しお远加したす。 結果の倀のタむプもResultになりたすが、Selectで宣蚀する新しいResultです。 䞀般に、これは1぀ではないにしおも、有効なアプロヌチです。



他のすべおの開発者にずっお、Cでそのようなコヌドを曞き始めるずすぐに、このようなものに芋え始めたす。 「これらはひどい恐ろしい䟋倖です。曞いおはいけたせん 圌らは悪です 誰も理解できず、デバッグできないコヌドを曞く方が良いでしょう」



CはFではなく、わずかに異なり、これが行われおいるこずに基づいお異なる抂念はありたせん。そしお、フクロりをそのように地球䞊に匕っ匵ろうずするず、それは穏やかで珍しいこずになりたす。



代わりに、文曞化され、誰もが知っおいる、開発者の間で認知的䞍協和を匕き起こさない組み蟌みの通垞のツヌルを䜿甚できたす。 ASP.NETにはグロヌバルなハンドラヌ䟋倖がありたす。



怜蚌に問題がある堎合は、コヌド400たたは422凊理䞍胜な゚ンティティを返す必芁があるこずを知っおいたす。 認蚌ず蚱可に問題がある堎合、401ず403がありたす。䜕かがうたくいかなかった堎合、䜕かがうたくいきたせんでした。 そしお、䜕かがうたくいかず、ナヌザヌに正確に䜕を䌝えたいのか、あなたの䟋倖タむプを定矩し、それがIHasUserMessageであるず蚀っお、このむンタヌフェヌスでMessageゲッタヌを宣蚀し、チェックしたすこのむンタヌフェヌスが実装されおいる堎合、メッセヌゞを受け取るこずができたす䟋倖からJSONでナヌザヌに枡したす。 このむンタヌフェむスが実装されおいない堎合は、䜕らかのシステム゚ラヌが発生したす。ナヌザヌに䜕か問題が発生したこずを䌝えるだけで、既にそれを行っおいたす。

ク゚リパむプラむン


チヌムでこれを終了し、Read-stackの内容を確認したす。 リク゚スト、怜蚌、レスポンス自䜓に぀いおは、ほが同じです。個別に停止するこずはありたせん。 ここには远加のキャッシュがあるかもしれたせんが、䞀般的にキャッシュにも倧きな問題はありたせん。

セキュリティ


セキュリティチェックを芋おみたしょう。 このリク゚ストを行うこずができるかどうかをチェックする同じセキュリティデコレヌタが存圚する堎合もありたす。



ただし、耇数のレコヌドを衚瀺し、リストを衚瀺する別のケヌスがありたす。䞀郚のナヌザヌには完党なリストを衚瀺する必芁がありたずえば、䞀郚のスヌパヌ管理者、他のナヌザヌには制限付きリストを衚瀺する必芁がありたす。 , , , , , .

問題は非垞に簡単に解決されたす . (IPermissionFilter), queryable queryable. , queryable, , where, : « ,  » — , permission'. , , permission', , permissionFilter' , . permission', , . queryable dbContext, . permissionFilter' , permissionFilter' . permissionFilter, , .



ORM, , Global Filters entity-? , context -.

Query Pipeline. Read Model


. CQRS , Dto, .



C#, , , LINQ, - , , , , . LinqQueryHandler'. constraint : Query, , . - , Dto .



Handle , . , TQuery . , queryable extension AutoMapper'. - , AutoMapper LINQ, , Select, .

, . , DotNext, , , , , , expression' , .

SQL


先に進みたす。 , DotNext', — SQL. Select , , , queryable- .



, . , Title, Title , . , . SubTitle, , , - , queryable- . , .

, . , , . , , . «JsonIgnore», . , , Dto. , , . JSON, , Created LastUpdated , SubTitle — , . , , , , , . , - .



. , -, , . , pipeline, . — , , . , SaveChanges, Query SaveChanges. , , , NuGet, .

. , - , , . , , , , , — . , , : « », — . .


, ?



- . .



, , , . MediatR , . , , — , MediatR pipeline behaviour. , Request/Response, RequestHandler' . Simple Injector, — .



, , , , TIn: ICommand.



Simple Injector' constraint' . , , , constraint', Handler', constraint. , constraint ICommand, SaveChanges constraint' ICommand, Simple Injector , constraint' , Handler'. , , , .

? Simple Injector MeriatR — , , Autofac', -, , , . , .

,


, «».



, «Clean architecture». .



- - , MVC, , .



, , , Angular, , , , . , : « — MVC-», : « Features, : , Blog - Import, - ».

, , , , MVC-, , - , . MVC . , , — . .





- , - -, .

-, , . , . , - , User Service, pull request', , User Service , . , - , - , . - , .

. , . , , , . , , , , , , , - . , ( , ), , «Delete»: , , . かなり快適です。

— «», , , , . , : , , , . , . , , . , , .

: . « », : , , . , , , , , , , . , . , - pull request , — , — - , . VCS : - , ? , - , , .



, , , . : . , . , , , , . , , , . , , . « », , . , , — , , .

: , - , . . - , , , , . - , - , , , , . .



たずめたす。 , IHandler . .

IHandler ICommandHandler IQueryHandler , . , , . , CommandHandler, CommandHandler', .

なぜそう , Query , Query — . , , , Hander, CommandHandler QueryHandler, - use case, .

— , , , , : , .

, . , . , -.

C# 8, nullable reference type . , , , , .

ChangeTracker' ORM.

Exception' — , F#, C#. , - , - , . , , Exception', , LINQ, , , , , , Dapper - , , , .NET.

, LINQ, , permission' — . , , - , , . , — .

. リンクは次のずおりです。






— . . — «Domain Modeling Made Functional», F#, F#, , , , , . C# , , Exception'.

, , — «Entity Framework Core In Action». , Entity Framework, , DDD ORM, , ORM DDD .

広告の分。 15-16 2019 .NET- DotNext Piter, . , .

Source: https://habr.com/ru/post/J447308/


All Articles