ドキュメントに記載されていないこと、または.Net Coreのリファクタリングの微妙な点

みなさんこんにちは! この資料を使用して、一方では冗長性に基づいて高可用性を実現するという長い歴史に捧げられた一連の記事を開きます。







順番に始めましょう。 .NETで記述された製品環境にあるモバイルアプリケーション用のAPIがあります。







そして最初のステップとして、それを.NET Coreに翻訳し、その過程で出会った複雑さを共有します。













Web APIに関するいくつかの事実:









タスクは非常に単純で簡単です。CDコンベアを構築するには、アプリケーションが迅速かつ動的に開発されるため、「完了手段のリリース」の原則に従う必要があります。







現在、現在の製品環境に展開されているため:







私たちはどこに行きますか:







どのようにそれを行うか:









すべてが非常にシンプルで論理的に見えます。 しかし、このパスに沿って、多くの問題、質問、困難などに必ず遭遇することは確実です。 そして、それらについて順番に説明してください。 我慢してビジネスに取り掛かってください。







モバイルサービスのコア部分のASP.NET Web Api 2からASP.NET Core 2への移行から始めます(これまでのところ、プッシュやバナーはありません。落とし穴があれば、別の記事で説明します)。







多くのタスクがあります。 それらのいくつかは、 公式マニュアルに従ってかなり標準的な方法で解決されますが、表面にはないものがあります。 そして、おそらく、それは同様の問題を解決するときに質問を引き起こすでしょう。 それらをあなたと共有したいと思います。







モバイルサービスのリファクタリング計画は次のとおりです。







1. Visual Studio 2017で新しいソリューションを作成する









2.外部依存関係を接続する







2.1 WCFサービスの接続







まず、 テーブルをチェックして、.Net Core 2.0がWCFクライアントの必要な機能をサポートしているかどうかを確認します。







以前はサービス参照と呼ばれていましたが、現在は接続サービスと呼ばれています。 [接続されたサービスの追加]メニューからWCF Webサービス参照プロジェクトに追加します。







ASP.NET CoreにはWeb.configファイルがなくなったため、すべてのWCFクライアント設定は生成されたReference.csコードに保存されます。







クライアントクラスは、追加のクライアント設定を入力するためのメソッドを提供します。







static partial void ConfigureEndpoint(ServiceEndpoint serviceEndpoint, ClientCredentials clientCredentials)









部分メソッドの実装を作成しています。 この場合、資格情報はこのメソッドで登録され、サービスで承認されます。







クライアント設定の変更に加えて、2番目の大きな変更は、クライアントに同期メソッドがなくなったことです。 非同期バージョンがすぐに使用されました。







2.2。 nuget-packages TimeZoneConverter、Swashbuckle、Mime、XmlSerializer.Generatorを接続します



パッケージTimeZoneConverter、Swashbuckle、Mimeの移植に問題はありませんでした。







発見について話します。 標準のXmlシリアライザーを使用する場合、重要な点があります。コードジェネレーターは、最初に使用されたときにランタイムで起動します。 したがって、これによりコールドスタート時間が長くなります。 この動作は、スタジオでJust My Codeが無効になっている場合に検出できます。 インターネットで簡単に検索した結果、 nml-package XmlSerializer.Generator見つかりました 。これはsgenに代わるもので、最小のNet Core 2およびNet Standard 2をサポートしています。その目的は、コンパイル時にシリアライザー xmlコードを生成することです。







プロジェクトに追加できることを嬉しく思います。 パッケージは、プロジェクトアセンブリシーケンスに自動的に含まれます。







制限事項:







a)ジェネレーターは、名前空間を考慮してクラス名を解決する方法を知らないため、DTOクラスの名前が重複している場合は、それを取り除く必要があります。







b)怠け者はxmltocsharp.azurewebsites.netを使用して、XML記述からDTOクラスを生成します。 オンラインサービスは、XmlRoot属性の広範囲にわたる分布に罪を犯します。 ジェネレーターは、この動作に腹を立てます。 火と剣は不要な場所XmlRootから咳き出します。







3. Global.asaxをStartup.csでブロードキャストします。









4.構成の構成







4.1。 IHostingEnvironment.Environmentを使用して環境をセットアップします







ビルドの出力で単一のdockerイメージを受け取り、すべてのテスト環境で変更せずに渡す予定です。 環境設定は、ASPNETCORE_ENVIRONMENT環境変数を使用して完全に制御する必要があります。 したがって、コードの条件付きコンパイルを最大限に取り除き、IHostingEnvironment.Environmentの値を確認します。







4.2。 AppSettingsブロックをWebから{Configuration} .configからAppSettings。{Environment} .jsonに移動します。







4.3。 開発環境、テスト環境、ステージ環境、リリース環境用のWCFサービスの構成を記述します。







5. HttpContextへの依存を削除します







HttpContextシングルトンがボックスでプレイされ、IHttpContextAccessorが彼に取って代わりました。







この変更の影響を受けた3つのことは次のとおりです。









HttpContext.Current.AddErrorsの代わりに、IHttpContextAccessor.HttpContext.Itemsを使用します









リクエスト数の増加に伴い、タイムスタンプによるリクエストの重複、つまり 同じタグが異なるリクエストに使用されました。 NET Coreでは、IHttpContextAccessor.HttpContext.TraceIdentifierプロパティを使用できます-本当に一意の識別子です。









6.コントローラーコードを転送する



6.1。 ASP NET WebApiはASP NET MVCに吸収されました。







影響を受けるルーティング、バインディング、ネゴシエーション、多くのクラスが消滅しました-ApiController以降をはじめ。







コントローラーコードを転送するときに最小限の血で対処するために、MVCベースのWeb Apiの概念をエミュレートする、 nugetパッケージWebApiCompatShimの形式で回避策があります。







すぐにレイヤーを放棄し、松葉杖でクリーンなMVCを使用して、痛みを感じ、最新のASP NET Coreを使用して近い将来にすべてを適切な形にするために行われる作業の量を明確に理解することにしました。 結局のところ、すべてがまったく悲しいわけではありません。









6.2。 HttpResponseExceptionを書く







昔ながらのプロジェクトでは、結果のオブジェクトはIActionResultではなくアクションに返されます。 .NET Coreでは、悲嘆について、HttpResponseExceptionを削除しました。プラットフォームの開発者は、頭脳の正しい使用に注意を払い、リクエストロジックに例外を使用しないよう指示しています。







良心に同意した後、ルーチンを後回しにし、HttpResponseExceptionとActionFilterを確認しました。これは、迅速な移行の一環として、すべてをIActionResultに書き換える時間が長すぎるためです。 さらに、各メソッドでProducesResponseType属性を指定する必要があります。これにより、swaggerはアクションの結果クラスを理解し、ドキュメントを生成します。







  public class HttpResponseException : Exception { public int StatusCode { get; private set; } public string ContentType { get; private set; } = "text/plain"; public HttpResponseException(int statusCode) { StatusCode = statusCode; } public HttpResponseException(int statusCode, string message) : base(message) { StatusCode = statusCode; } } public class HttpResponseExceptionFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception is HttpResponseException) { var ex = (HttpResponseException)context.Exception; context.Result = new ContentResult() { StatusCode = ex.StatusCode, Content = ex.Message, ContentType = ex.ContentType }; context.ExceptionHandled = true; } } }
      
      





ファイルのダウンロードと送信の方法には例外があります。ここでは、正直に言うと、HttpRequestMessageとHttpContentからFileContentResultとIFormFileに書き換えました。それ以外の場合は不可能です。







7.ドキュメント









PSリファクタリングが長かったとは言いませんが、それでも多くの労力が必要でした。 この経験は私たち(そしてあなた)と共にあり、次回はこの方法でより速く行くことができます。







次のシリーズでは、Dockerコンテナでのアセンブリの構成に関する調査結果を共有します。 彼らが言うように、「切り替えないでください。」








All Articles