From 5f9944f6245179820bb83519b1be090b7d5bca4a Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:10:27 +0300 Subject: [PATCH 01/15] ABP CLI microservice creation should edit tye.yml according to ui type resolves https://github.com/volosoft/volo/issues/5689 --- .../Steps/RemoveProjectFromTyeStep.cs | 54 +++++++++++++++++++ .../Microservice/MicroserviceTemplateBase.cs | 10 ++++ 2 files changed, 64 insertions(+) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs new file mode 100644 index 0000000000..9804ef7c4b --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class RemoveProjectFromTyeStep : ProjectBuildPipelineStep + { + private readonly string _name; + + public RemoveProjectFromTyeStep(string name) + { + _name = name; + } + + public override void Execute(ProjectBuildContext context) + { + var tyeFile = context.Files.FirstOrDefault(f => f.Name == "/tye.yaml"); + + if (tyeFile == null) + { + return; + } + + var lines = tyeFile.Content.SplitToLines(); + var newLines = new List(); + + var nameLine = $"- name:"; + var isOneOfTargetLines = false; + + foreach (var line in lines) + { + if (line.Equals($"{nameLine} {_name}")) + { + isOneOfTargetLines = true; + continue; + } + + if (line.StartsWith(nameLine)) + { + isOneOfTargetLines = false; + } + + if (!isOneOfTargetLines) + { + newLines.Add(line); + } + } + + tyeFile.SetContent(String.Join(Environment.NewLine, newLines)); + } + + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs index 0a56f5272a..1efbe09ff1 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs @@ -36,9 +36,13 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web",null, "/applications/web/src/MyCompanyName.MyProjectName.Web")); steps.Add(new RemoveFolderStep("/applications/web")); + steps.Add(new RemoveProjectFromTyeStep("web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); steps.Add(new RemoveFolderStep("/applications/blazor")); + steps.Add(new RemoveProjectFromTyeStep("blazor")); + steps.Add(new RemoveFolderStep("/angular")); break; @@ -46,9 +50,12 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web",null, "/applications/web/src/MyCompanyName.MyProjectName.Web")); steps.Add(new RemoveFolderStep("/applications/web")); + steps.Add(new RemoveProjectFromTyeStep("web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); steps.Add(new RemoveFolderStep("/applications/blazor")); + steps.Add(new RemoveProjectFromTyeStep("blazor")); break; case UiFramework.Blazor: @@ -56,6 +63,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice "/applications/web/src/MyCompanyName.MyProjectName.Web")); steps.Add(new RemoveFolderStep("/applications/web")); steps.Add(new RemoveFolderStep("/angular")); + steps.Add(new RemoveProjectFromTyeStep("web")); break; case UiFramework.Mvc: @@ -63,6 +71,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); steps.Add(new RemoveFolderStep("/applications/blazor")); + steps.Add(new RemoveProjectFromTyeStep("blazor")); + steps.Add(new RemoveFolderStep("/angular")); break; } From a44f9a1a8c2596efb81f62dd89ebf977fb90d52f Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:17:49 +0300 Subject: [PATCH 02/15] Cli SolutionRenameStep: rename lowercase --- .../Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs index 1ea30fe783..7da16ae8f3 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs @@ -90,6 +90,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps RenameHelper.RenameAll(_entries, _projectNamePlaceHolder, _projectName); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToCamelCase(), _projectName.ToCamelCase()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToKebabCase(), _projectName.ToKebabCase()); + RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToLowerInvariant(), _projectName.ToLowerInvariant()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToSnakeCase().ToUpper(), _projectName.ToSnakeCase().ToUpper()); } } From 96f0c03fd84f77798a662227d81a3f7419c30cb3 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:22:10 +0300 Subject: [PATCH 03/15] Update RemoveProjectFromTyeStep.cs --- .../ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs index 9804ef7c4b..1c51e22bc9 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromTyeStep.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps return; } - var lines = tyeFile.Content.SplitToLines(); + var lines = tyeFile.GetLines(); var newLines = new List(); var nameLine = $"- name:"; From 003eca038f10909a185c4ca9d2faa2e56508556c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 4 Mar 2021 15:26:59 +0300 Subject: [PATCH 04/15] Revert "Cli SolutionRenameStep: rename lowercase" This reverts commit a44f9a1a8c2596efb81f62dd89ebf977fb90d52f. --- .../Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs index 7da16ae8f3..1ea30fe783 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs @@ -90,7 +90,6 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps RenameHelper.RenameAll(_entries, _projectNamePlaceHolder, _projectName); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToCamelCase(), _projectName.ToCamelCase()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToKebabCase(), _projectName.ToKebabCase()); - RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToLowerInvariant(), _projectName.ToLowerInvariant()); RenameHelper.RenameAll(_entries, _projectNamePlaceHolder.ToSnakeCase().ToUpper(), _projectName.ToSnakeCase().ToUpper()); } } From 4d9f49d25bb71ae8280e22d1bff3d59d957380d7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 5 Mar 2021 12:02:24 +0300 Subject: [PATCH 05/15] Set random port when a new Microservice is created resolves https://github.com/volosoft/volo/issues/5716 --- .../MicroserviceServiceRandomPortStep.cs | 78 +++++++++++++++++++ .../MicroserviceServiceTemplateBase.cs | 6 ++ 2 files changed, 84 insertions(+) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs new file mode 100644 index 0000000000..88a19b43af --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MicroserviceServiceRandomPortStep.cs @@ -0,0 +1,78 @@ +using System; +using System.IO; +using System.Linq; +using Volo.Abp.Cli.Commands; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class MicroserviceServiceRandomPortStep : ProjectBuildPipelineStep + { + private readonly string _defaultPort = string.Empty; + private string _tyeFileContent = null; + + public MicroserviceServiceRandomPortStep(string defaultPort) + { + _defaultPort = defaultPort; + } + + public override void Execute(ProjectBuildContext context) + { + var newPort = GetNewRandomPort(context); + + var targetFiles = context.Files.Where(f=> f.Name.EndsWith("launchSettings.json") || f.Name.EndsWith("appsettings.json")).ToList(); + + foreach (var file in targetFiles) + { + file.SetContent(file.Content.Replace(_defaultPort, newPort)); + } + } + + private string GetNewRandomPort(ProjectBuildContext context) + { + string newPort; + var rnd = new Random(); + var tryCount = 0; + + do + { + newPort = rnd.Next(44350, 45350).ToString(); + + if (tryCount++ > 2000) + { + break; + } + + } while (PortExistsForAnotherService(context, newPort)); + + return newPort; + } + + private bool PortExistsForAnotherService(ProjectBuildContext context, string newPort) + { + return ReadTyeFileContent(context).SplitToLines().Any(l => l.Contains("port") && l.Contains(newPort)); + } + + private string ReadTyeFileContent(ProjectBuildContext context) + { + if (_tyeFileContent != null) + { + return _tyeFileContent; + } + + var solutionFolderPath = context.BuildArgs.ExtraProperties[NewCommand.Options.OutputFolder.Short] ?? + context.BuildArgs.ExtraProperties[NewCommand.Options.OutputFolder.Long] ?? + Directory.GetCurrentDirectory(); + + var tyeFilePath = Path.Combine(solutionFolderPath, "tye.yaml"); + + if (!File.Exists(tyeFilePath)) + { + return String.Empty; + } + + _tyeFileContent = File.ReadAllText(tyeFilePath); + + return _tyeFileContent; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs index de589336b0..54ec4894b9 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs @@ -31,6 +31,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice var steps = new List(); DeleteUnrelatedUiProject(context, steps); + SetRandomPortForHostProject(context, steps); RandomizeStringEncryption(context, steps); return steps; @@ -54,6 +55,11 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice } } + private static void SetRandomPortForHostProject(ProjectBuildContext context, List steps) + { + steps.Add(new MicroserviceServiceRandomPortStep("44371")); + } + private static void RandomizeStringEncryption(ProjectBuildContext context, List steps) { steps.Add(new RandomizeStringEncryptionStep()); From 202af0eb50237fbb217c9065926e8fa7e9aac5e2 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 5 Mar 2021 12:03:38 +0300 Subject: [PATCH 06/15] add HTTP Error Handling section to HTTP Requests document --- docs/en/UI/Angular/HTTP-Requests.md | 99 +++++++++++++++++- .../custom-error-handler-404-component.jpg | Bin 0 -> 6153 bytes .../custom-error-handler-toaster-message.jpg | Bin 0 -> 7589 bytes 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 docs/en/UI/Angular/images/custom-error-handler-404-component.jpg create mode 100644 docs/en/UI/Angular/images/custom-error-handler-toaster-message.jpg diff --git a/docs/en/UI/Angular/HTTP-Requests.md b/docs/en/UI/Angular/HTTP-Requests.md index ab1ac04097..f307c5811d 100644 --- a/docs/en/UI/Angular/HTTP-Requests.md +++ b/docs/en/UI/Angular/HTTP-Requests.md @@ -27,13 +27,13 @@ An `HttpInterceptor` is able to catch `HttpErrorResponse`  and can be used for ## RestService -ABP core module has a utility service for HTTP requests: `RestService`. Unless explicitly configured otherwise, it catches HTTP errors and dispatches a `RestOccurError` action. This action is then captured by the `ErrorHandler` introduced by the `ThemeSharedModule`. Since you should already import this module in your app, when the `RestService` is used, all HTTP errors get automatically handled by deafult. +ABP core module has a utility service for HTTP requests: `RestService`. Unless explicitly configured otherwise, it catches HTTP errors and dispatches a `RestOccurError` action. This action is then captured by the `ErrorHandler` introduced by the `ThemeSharedModule`. Since you should already import this module in your app, when the `RestService` is used, all HTTP errors get automatically handled by default. ### Getting Started with RestService -In order to use the `RestService`, you must inject it in your class as a dependency. +In order to use the `RestService`, you must inject it in your class as a dependency. ```js import { RestService } from '@abp/ng.core'; @@ -200,6 +200,99 @@ getSomeCustomHeaderValue() { } ``` +You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10). -You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10). +## HTTP Error Handling + +When the `RestService` is used, all HTTP errors are automatically handled by `ErrorHandler` which is a service that exposed by the `@abp/ng.theme.shared` package. + +### Custom HTTP Error Handler + +A custom HTTP error handler can be registered to an injection token named `HTTP_ERROR_HANDLER`. If a custom handler function is registered, the `ErrorHandler` executes that function. + +See an example: + +```js +// http-error-handler.ts +import { ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core'; +import { ToasterService } from '@abp/ng.theme.shared'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Injector } from '@angular/core'; +import { throwError } from 'rxjs'; +import { Error404Component } from './error404/error404.component'; + +export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) { + if (httpError.status === 400) { + const toaster = injector.get(ToasterService); + toaster.error(httpError.error?.error?.message || 'Bad request!', '400'); + return; + } + + if (httpError.status === 404) { + const contentProjection = injector.get(ContentProjectionService); + contentProjection.projectContent(PROJECTION_STRATEGY.AppendComponentToBody(Error404Component)); + return; + } + + return throwError(httpError); +} + +// app.module.ts +import { Error404Component } from './error404/error404.component'; +import { handleHttpErrors } from './http-error-handling'; +import { HTTP_ERROR_HANDLER, ... } from '@abp/ng.theme.shared'; + +@NgModule({ + // ... + providers: [ + // ... + { provide: HTTP_ERROR_HANDLER, useValue: handleHttpErrors } + ], + declarations: [ + //... + Error404Component], +}) +export class AppModule {} +``` + +In the example above: + + - Created a function named `handleHttpErrors` and defined as value of the `HTTP_ERROR_HANDLER` provider in app.module. After this, the function executes when an HTTP error occurs. + - 400 bad request errors is handled. When a 400 error occurs, backend error message will be displayed as shown below: + + ![custom-error-handler-toaster-message](images/custom-error-handler-toaster-message.jpg) + + - 404 not found errors is handled. When a 404 error occurs, `Error404Component` will be appended to the `` as shown below: + +![custom-error-handler-404-component](images/custom-error-handler-404-component.jpg) + + - Since `throwError(httpError)` is returned at bottom of the `handleHttpErrors`, the `ErrorHandler` will handle the HTTP errors except 400 and 404 errors. + + +**Note 1:** If you put `return` to next line of handling an error, default error handling will not work for that error. + +```js +export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) { + if (httpError.status === 403) { + // handle 403 errors here + return; // put return to skip default error handling + } +} +``` + +**Note 2:** If you put `return throwError(httpError)`, default error handling will work. + - `throwError` is a function. It can be imported from `rxjs`. + - `httpError` is the second parameter of the error handler function which is registered to the `HTTP_ERROR_HANDLER` provider. Type of the `httpError` is `HttpErrorResponse`. + +```js +export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) { + if (httpError.status === 500) { + // handle 500 errors here + return; + } + + // you can return the throwError(httpError) at bottom of the function to run the default handler of ABP for HTTP errors that you didn't handle above. + return throwError(httpError) +} +``` diff --git a/docs/en/UI/Angular/images/custom-error-handler-404-component.jpg b/docs/en/UI/Angular/images/custom-error-handler-404-component.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e4b2f15c5075991203d8ad91bbd4eb42a9070d51 GIT binary patch literal 6153 zcmeIwc}&w+902fNDM#g~l&XV3X@pr+eu}EDr?l4+cOW5D>aH0o@xQ2rxA+M%x{2rw`J8GsEJohDJ{xaV`E?;}P<)0Zpre2T2{!!0_0(t?xfL=f^pcnXm3K(+j9WPHx3zCx3(gYMCztm3X zI6X9xOCFiX3P#MuKN@l&ctyLQ8a-xZQpJzKMt!tU6;uo1)pey45N!#fh<==__C@q2 z%y5p(hBo8F^h`aXwPRFqssS^X!W-|JRAPEvcluO!o-B@UQR{--G;7+g|D;@{Qm))rJN zb$~DZ6@GVeCI;>?-J8UY&{m4Kuu|BoYE7uTR2p$-__xLPoAFzfPdl7jXjet-_=njj z=Tby5TF4$TlAZ{=vN8&A|UKK(#_nV(8;h>sO}hJ`epn4A;2#4bDO0Qat@Y(+}? zQ32OJzLMzGdYS?k9(F78O}8WOI)@@PJqZgZB^<-WW(8#2#f^$W;s|!a#VmFOlN`&u z<+Sw7Ul|jAL{gYpi9&h1tJ}HS9v!f`?=pbFL7Itd)BbZ@*l*IdD5tK2@orsRcOMy@pOsv!^U8_JN3aS$;vlywl3zjJ6h? zlgR2;I!5;vCP&x%wMfsnX*jg1uf{g05vadQ$A_oAymN4!+(xo}B!09JeV#_3WJ~a7 zA-{g$_-8lcW~&D0;9gHs)T|^WnQ#(^JuA#ZLi5UOse;Mu#k6L{7=xR^;WJyh*e&mt zRMR2ym5~RTEf`HFH72S*Ji~jA=vLJ~r&9Mii=mNm#gZHLL79Sjb2LMgieErTJ!ZA3 zZm?5DWC=ExK)lo@E461NGDMWvh5S0K4*20QhP)}) zA0{}_tLgje!);I$_`K%6U(DU6M{yOGI9r#(bIGo0o&mR1t4^~O<@DEu2$gxFaEdNy zmf}YmrK3C~R9RB85(w|?^K^B=2VHp{Tkp@0KU8~$J0(NYuH6q&Ts;$(mb`%7LsZz* zQpzaTP-cer>j?afm$W}_{?zj^1PdPO%k=09iY-M&$VNVFFLvij~i{5*FK4eM# zK57AJL_UDxHp)C;+4(inUtSd4&TpaZ_8g^TDM^zs{XZb1xJbbMl_@9TiT z=HhaReNZm`*oo=E_5!Y( BlV|_{ literal 0 HcmV?d00001 diff --git a/docs/en/UI/Angular/images/custom-error-handler-toaster-message.jpg b/docs/en/UI/Angular/images/custom-error-handler-toaster-message.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c1cced8237a13bf0e18ec9d4e4b08ddb6f527c26 GIT binary patch literal 7589 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 S7su<%e?BPuAGJ7lJoaCszdtVk literal 0 HcmV?d00001 From 9dd4ee1674f0fe7fd8e04ec3e9716fdb1cc9fcc0 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 5 Mar 2021 12:05:03 +0300 Subject: [PATCH 07/15] add an import to the HTTP-Request.md --- docs/en/UI/Angular/HTTP-Requests.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/UI/Angular/HTTP-Requests.md b/docs/en/UI/Angular/HTTP-Requests.md index f307c5811d..aeb55578b8 100644 --- a/docs/en/UI/Angular/HTTP-Requests.md +++ b/docs/en/UI/Angular/HTTP-Requests.md @@ -286,6 +286,8 @@ export function handleHttpErrors(injector: Injector, httpError: HttpErrorRespons - `httpError` is the second parameter of the error handler function which is registered to the `HTTP_ERROR_HANDLER` provider. Type of the `httpError` is `HttpErrorResponse`. ```js +import { throwError } from 'rxjs'; + export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) { if (httpError.status === 500) { // handle 500 errors here From fe5399026fb75468a0692cf616acb14e941d7767 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 5 Mar 2021 12:10:06 +0300 Subject: [PATCH 08/15] create HTTP_ERROR_HANDLER injection token --- .../packages/theme-shared/src/lib/models/common.ts | 9 ++++++++- .../theme-shared/src/lib/tokens/http-error.token.ts | 6 ++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts index 64047e0db7..0e8dd9e592 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/common.ts @@ -1,5 +1,7 @@ -import { Type } from '@angular/core'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Injector, Type } from '@angular/core'; import { Validation } from '@ngx-validate/core'; +import { Observable } from 'rxjs'; export interface RootParams { httpErrorConfig: HttpErrorConfig; @@ -17,4 +19,9 @@ export interface HttpErrorConfig { }; } +export type HttpErrorHandler = ( + injector: Injector, + httpError: HttpErrorResponse, +) => Observable; + export type LocaleDirection = 'ltr' | 'rtl'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts b/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts index 62f2d2d593..39cb43a350 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts @@ -1,5 +1,5 @@ import { InjectionToken } from '@angular/core'; -import { HttpErrorConfig } from '../models/common'; +import { HttpErrorConfig, HttpErrorHandler } from '../models/common'; export function httpErrorConfigFactory(config = {} as HttpErrorConfig) { if (config.errorScreen && config.errorScreen.component && !config.errorScreen.forWhichErrors) { @@ -13,4 +13,6 @@ export function httpErrorConfigFactory(config = {} as HttpErrorConfig) { } as HttpErrorConfig; } -export const HTTP_ERROR_CONFIG = new InjectionToken('HTTP_ERROR_CONFIG'); +export const HTTP_ERROR_CONFIG = new InjectionToken('HTTP_ERROR_CONFIG'); + +export const HTTP_ERROR_HANDLER = new InjectionToken('HTTP_ERROR_HANDLER'); From 7e46a48e78d686e37bc2ebcde540fb8805e0a8ca Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 5 Mar 2021 12:11:05 +0300 Subject: [PATCH 09/15] execute custom error handler if it exists --- .../src/lib/handlers/error.handler.ts | 229 ++++++++++-------- 1 file changed, 124 insertions(+), 105 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 1835b80eef..cad4567285 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -12,13 +12,14 @@ import { } from '@angular/core'; import { NavigationError, ResolveEnd } from '@angular/router'; import { Actions, ofActionSuccessful } from '@ngxs/store'; -import { Observable, Subject } from 'rxjs'; -import { filter, map } from 'rxjs/operators'; +import { Observable, of, Subject, throwError } from 'rxjs'; +import { catchError, filter, map, switchMap } from 'rxjs/operators'; import snq from 'snq'; import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http-error-wrapper.component'; import { ErrorScreenErrorCodes, HttpErrorConfig } from '../models/common'; import { Confirmation } from '../models/confirmation'; import { ConfirmationService } from '../services/confirmation.service'; +import { HTTP_ERROR_HANDLER } from '../tokens/http-error.token'; export const DEFAULT_ERROR_MESSAGES = { defaultError: { @@ -70,28 +71,32 @@ export const DEFAULT_ERROR_LOCALIZATIONS = { export class ErrorHandler { componentRef: ComponentRef; + protected httpErrorHandler = this.injector.get(HTTP_ERROR_HANDLER, (_, err: HttpErrorResponse) => + throwError(err), + ); + constructor( - private actions: Actions, - private routerEvents: RouterEvents, - private confirmationService: ConfirmationService, - private cfRes: ComponentFactoryResolver, - private rendererFactory: RendererFactory2, - private injector: Injector, - @Inject('HTTP_ERROR_CONFIG') private httpErrorConfig: HttpErrorConfig, + protected actions: Actions, + protected routerEvents: RouterEvents, + protected confirmationService: ConfirmationService, + protected cfRes: ComponentFactoryResolver, + protected rendererFactory: RendererFactory2, + protected injector: Injector, + @Inject('HTTP_ERROR_CONFIG') protected httpErrorConfig: HttpErrorConfig, ) { this.listenToRestError(); this.listenToRouterError(); this.listenToRouterDataResolved(); } - private listenToRouterError() { + protected listenToRouterError() { this.routerEvents .getNavigationEvents('Error') .pipe(filter(this.filterRouteErrors)) .subscribe(() => this.show404Page()); } - private listenToRouterDataResolved() { + protected listenToRouterDataResolved() { this.routerEvents .getEvents(ResolveEnd) .pipe(filter(() => !!this.componentRef)) @@ -101,113 +106,127 @@ export class ErrorHandler { }); } - private listenToRestError() { + protected listenToRestError() { this.actions .pipe( ofActionSuccessful(RestOccurError), map(action => action.payload), filter(this.filterRestErrors), + switchMap(this.executeErrorHandler), ) - .subscribe(err => { - const body = snq(() => err.error.error, { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, - }); + .subscribe(); + } - if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) { - const confirmation$ = this.showError(null, null, body); + private executeErrorHandler = err => { + const returnValue = this.httpErrorHandler(this.injector, err); - if (err.status === 401) { - confirmation$.subscribe(() => { - this.navigateToLogin(); - }); - } - } else { - switch (err.status) { - case 401: - this.canCreateCustomError(401) - ? this.show401Page() - : this.showError( - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.title, - }, - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.details, - }, - ).subscribe(() => this.navigateToLogin()); - break; - case 403: - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError403.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.title, - }, - details: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError403.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.details, - }, - status: 403, - }); - break; - case 404: - this.canCreateCustomError(404) - ? this.show404Page() - : this.showError( - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.details, - }, - { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title, - }, - ); - break; - case 500: - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError500.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.title, + return (returnValue instanceof Observable ? returnValue : of(null)).pipe( + catchError(err => { + this.handleError(err); + return of(null); + }), + ); + }; + + private handleError(err: any) { + const body = snq(() => err.error.error, { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + }); + + if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) { + const confirmation$ = this.showError(null, null, body); + + if (err.status === 401) { + confirmation$.subscribe(() => { + this.navigateToLogin(); + }); + } + } else { + switch (err.status) { + case 401: + this.canCreateCustomError(401) + ? this.show401Page() + : this.showError( + { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.title, }, - details: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError500.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.details, + { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.details, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.details, }, - status: 500, - }); - break; - case 0: - if (err.statusText === 'Unknown Error') { - this.createErrorComponent({ - title: { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, - }, - details: err.message, - isHomeShow: false, - }); - } - break; - default: - this.showError( + ).subscribe(() => this.navigateToLogin()); + break; + case 403: + this.createErrorComponent({ + title: { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError403.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.title, + }, + details: { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError403.details, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.details, + }, + status: 403, + }); + break; + case 404: + this.canCreateCustomError(404) + ? this.show404Page() + : this.showError( { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.details, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.details, + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.details, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.details, }, { - key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, - defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title, }, ); - break; + break; + case 500: + this.createErrorComponent({ + title: { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError500.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.title, + }, + details: { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError500.details, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.details, + }, + status: 500, + }); + break; + case 0: + if (err.statusText === 'Unknown Error') { + this.createErrorComponent({ + title: { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + }, + details: err.message, + isHomeShow: false, + }); } - } - }); + break; + default: + this.showError( + { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.details, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.details, + }, + { + key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, + defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, + }, + ); + break; + } + } } - private show401Page() { + protected show401Page() { this.createErrorComponent({ title: { key: DEFAULT_ERROR_LOCALIZATIONS.defaultError401.title, @@ -217,7 +236,7 @@ export class ErrorHandler { }); } - private show404Page() { + protected show404Page() { this.createErrorComponent({ title: { key: DEFAULT_ERROR_LOCALIZATIONS.defaultError404.title, @@ -227,7 +246,7 @@ export class ErrorHandler { }); } - private showError( + protected showError( message?: LocalizationParam, title?: LocalizationParam, body?: any, @@ -256,7 +275,7 @@ export class ErrorHandler { }); } - private navigateToLogin() { + protected navigateToLogin() { this.injector.get(AuthService).initLogin(); } @@ -304,13 +323,13 @@ export class ErrorHandler { ); } - private filterRestErrors = ({ status }: HttpErrorResponse): boolean => { + protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => { if (typeof status !== 'number') return false; return this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0; }; - private filterRouteErrors = (navigationError: NavigationError): boolean => { + protected filterRouteErrors = (navigationError: NavigationError): boolean => { return ( snq(() => navigationError.error.message.indexOf('Cannot match') > -1) && this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === 404) < 0 From 442144e9f0ccaa4f207bab84139f3772d9fcebe8 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 5 Mar 2021 12:55:48 +0300 Subject: [PATCH 10/15] fix a lint error --- .../packages/theme-shared/src/lib/handlers/error.handler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index cad4567285..1001c98085 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -117,8 +117,8 @@ export class ErrorHandler { .subscribe(); } - private executeErrorHandler = err => { - const returnValue = this.httpErrorHandler(this.injector, err); + private executeErrorHandler = error => { + const returnValue = this.httpErrorHandler(this.injector, error); return (returnValue instanceof Observable ? returnValue : of(null)).pipe( catchError(err => { From 316fdb63eaf3b55a0c2f93b1dd848220c6759197 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 5 Mar 2021 14:52:40 +0300 Subject: [PATCH 11/15] fix router events service intro --- docs/en/UI/Angular/Router-Events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Router-Events.md b/docs/en/UI/Angular/Router-Events.md index 011d405b22..1d36c3a211 100644 --- a/docs/en/UI/Angular/Router-Events.md +++ b/docs/en/UI/Angular/Router-Events.md @@ -1,6 +1,6 @@ # Router Events Simplified -`RouterEvents` is a utility service to provide an easy implementation for one of the most frequent needs in Angular templates: `TrackByFunction`. Please see [this page in Angular docs](https://angular.io/guide/template-syntax#ngfor-with-trackby) for its purpose. +`RouterEvents` is a utility service for filtering specific router events and reacting to them. Please see [this page in Angular docs](https://angular.io/api/router/Event) for available router events. From 859c4e9a6c32ee51d910715715633709e9e831eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 Mar 2021 17:11:51 +0300 Subject: [PATCH 12/15] Resolves #7965: Logging on Service Registration. --- .../ServiceCollectionLoggingExtensions.cs | 12 +++++++++ .../Volo/Abp/AbpApplicationBase.cs | 21 +++++++++++++++ .../InternalServiceCollectionExtensions.cs | 2 ++ .../Volo/Abp/Logging/AbpInitLogEntry.cs | 26 +++++++++++++++++++ .../Volo/Abp/Logging/DefaultInitLogger.cs | 24 +++++++++++++++++ .../Volo/Abp/Logging/IInitLogger.cs | 16 ++++++++++++ .../Volo/Abp/Modularity/AbpModuleHelper.cs | 16 +++++++++--- .../Volo/Abp/Modularity/ModuleLoader.cs | 7 +++-- .../Volo/Abp/Modularity/ModuleManager.cs | 12 --------- .../PlugIns/PlugInSourceExtensions.cs | 5 ++-- .../Modularity/PlugIns/PlugInSourceList.cs | 5 ++-- .../Volo/Abp/Modularity/ModuleLoader_Tests.cs | 8 +++++- 12 files changed, 131 insertions(+), 23 deletions(-) create mode 100644 framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs new file mode 100644 index 0000000000..48921cb99b --- /dev/null +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Logging; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class ServiceCollectionLoggingExtensions + { + public static IInitLogger GetInitLogger(this IServiceCollection services) + { + return services.GetSingletonInstance(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 1e5b251ca0..256a1dd05d 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.Internal; +using Volo.Abp.Logging; using Volo.Abp.Modularity; namespace Volo.Abp @@ -71,11 +73,30 @@ namespace Volo.Abp { using (var scope = ServiceProvider.CreateScope()) { + WriteInitLogs(scope.ServiceProvider); scope.ServiceProvider .GetRequiredService() .InitializeModules(new ApplicationInitializationContext(scope.ServiceProvider)); } } + + protected virtual void WriteInitLogs(IServiceProvider serviceProvider) + { + var logger = serviceProvider.GetService>(); + if (logger == null) + { + return; + } + + var initLogger = serviceProvider.GetRequiredService(); + + foreach (var entry in initLogger.Entries) + { + logger.LogWithLevel(entry.Level, entry.Message, entry.Exception); + } + + initLogger.Entries.Clear(); + } protected virtual IReadOnlyList LoadModules(IServiceCollection services, AbpApplicationCreationOptions options) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs index 83a7ec163e..c116a20080 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.Logging; using Volo.Abp.Modularity; using Volo.Abp.Reflection; @@ -35,6 +36,7 @@ namespace Volo.Abp.Internal services.TryAddSingleton(moduleLoader); services.TryAddSingleton(assemblyFinder); services.TryAddSingleton(typeFinder); + services.TryAddSingleton(new DefaultInitLogger()); services.AddAssemblyOf(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs new file mode 100644 index 0000000000..17a346fa1c --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs @@ -0,0 +1,26 @@ +using System; +using JetBrains.Annotations; +using Microsoft.Extensions.Logging; + +namespace Volo.Abp.Logging +{ + public class AbpInitLogEntry + { + public LogLevel Level { get; } + + public string Message { get; } + + [CanBeNull] + public Exception Exception { get; } + + public AbpInitLogEntry( + LogLevel level, + string message, + Exception exception) + { + Level = level; + Message = message; + Exception = exception; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs new file mode 100644 index 0000000000..e1f7344f39 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; + +namespace Volo.Abp.Logging +{ + public class DefaultInitLogger : IInitLogger + { + public List Entries { get; } + + public DefaultInitLogger() + { + Entries = new List(); + } + + public void Log( + LogLevel logLevel, + string message, + Exception exception = null) + { + Entries.Add(new AbpInitLogEntry(logLevel, message, exception)); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs new file mode 100644 index 0000000000..5c549682e9 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; + +namespace Volo.Abp.Logging +{ + public interface IInitLogger + { + public List Entries { get; } + + void Log( + LogLevel logLevel, + string message, + Exception exception = null); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs index d58483811b..9331014623 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs @@ -2,15 +2,18 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using Microsoft.Extensions.Logging; +using Volo.Abp.Logging; namespace Volo.Abp.Modularity { internal static class AbpModuleHelper { - public static List FindAllModuleTypes(Type startupModuleType) + public static List FindAllModuleTypes(Type startupModuleType, IInitLogger logger) { var moduleTypes = new List(); - AddModuleAndDependenciesResursively(moduleTypes, startupModuleType); + logger.Log(LogLevel.Information, "Loaded ABP modules:"); + AddModuleAndDependenciesResursively(moduleTypes, startupModuleType, logger); return moduleTypes; } @@ -35,7 +38,11 @@ namespace Volo.Abp.Modularity return dependencies; } - private static void AddModuleAndDependenciesResursively(List moduleTypes, Type moduleType) + private static void AddModuleAndDependenciesResursively( + List moduleTypes, + Type moduleType, + IInitLogger logger, + int depth = 0) { AbpModule.CheckAbpModuleType(moduleType); @@ -45,10 +52,11 @@ namespace Volo.Abp.Modularity } moduleTypes.Add(moduleType); + logger.Log(LogLevel.Information, $"{new string(' ', depth * 2)}- {moduleType.FullName}"); foreach (var dependedModuleType in FindDependedModuleTypes(moduleType)) { - AddModuleAndDependenciesResursively(moduleTypes, dependedModuleType); + AddModuleAndDependenciesResursively(moduleTypes, dependedModuleType, logger, depth + 1); } } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs index 7e7e69d457..56ee2f5d71 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Logging; using Volo.Abp.Modularity.PlugIns; namespace Volo.Abp.Modularity @@ -43,14 +44,16 @@ namespace Volo.Abp.Modularity Type startupModuleType, PlugInSourceList plugInSources) { + var initLogger = services.GetInitLogger(); + //All modules starting from the startup module - foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType)) + foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType, initLogger)) { modules.Add(CreateModuleDescriptor(services, moduleType)); } //Plugin modules - foreach (var moduleType in plugInSources.GetAllModules()) + foreach (var moduleType in plugInSources.GetAllModules(initLogger)) { if (modules.Any(m => m.Type == moduleType)) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs index 70b9036150..764acf1289 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleManager.cs @@ -32,8 +32,6 @@ namespace Volo.Abp.Modularity public void InitializeModules(ApplicationInitializationContext context) { - LogListOfModules(); - foreach (var contributor in _lifecycleContributors) { foreach (var module in _moduleContainer.Modules) @@ -52,16 +50,6 @@ namespace Volo.Abp.Modularity _logger.LogInformation("Initialized all ABP modules."); } - private void LogListOfModules() - { - _logger.LogInformation("Loaded ABP modules:"); - - foreach (var module in _moduleContainer.Modules) - { - _logger.LogInformation("- " + module.Type.FullName); - } - } - public void ShutdownModules(ApplicationShutdownContext context) { var modules = _moduleContainer.Modules.Reverse().ToList(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs index bf44f94605..b041cd160d 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs @@ -1,19 +1,20 @@ using System; using System.Linq; using JetBrains.Annotations; +using Volo.Abp.Logging; namespace Volo.Abp.Modularity.PlugIns { public static class PlugInSourceExtensions { [NotNull] - public static Type[] GetModulesWithAllDependencies([NotNull] this IPlugInSource plugInSource) + public static Type[] GetModulesWithAllDependencies([NotNull] this IPlugInSource plugInSource, IInitLogger logger) { Check.NotNull(plugInSource, nameof(plugInSource)); return plugInSource .GetModules() - .SelectMany(AbpModuleHelper.FindAllModuleTypes) + .SelectMany(type => AbpModuleHelper.FindAllModuleTypes(type, logger)) .Distinct() .ToArray(); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs index 1e96e26e14..1d5509b359 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs @@ -2,16 +2,17 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; +using Volo.Abp.Logging; namespace Volo.Abp.Modularity.PlugIns { public class PlugInSourceList : List { [NotNull] - internal Type[] GetAllModules() + internal Type[] GetAllModules(IInitLogger logger) { return this - .SelectMany(pluginSource => pluginSource.GetModulesWithAllDependencies()) + .SelectMany(pluginSource => pluginSource.GetModulesWithAllDependencies(logger)) .Distinct() .ToArray(); } diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs index 3541f9b78e..cc0117e184 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Shouldly; +using Volo.Abp.Logging; using Volo.Abp.Modularity.PlugIns; using Xunit; @@ -11,7 +12,12 @@ namespace Volo.Abp.Modularity public void Should_Load_Modules_By_Dependency_Order() { var moduleLoader = new ModuleLoader(); - var modules = moduleLoader.LoadModules(new ServiceCollection(), typeof(MyStartupModule), new PlugInSourceList()); + var modules = moduleLoader.LoadModules( + new ServiceCollection() + .AddSingleton(new DefaultInitLogger()), + typeof(MyStartupModule), + new PlugInSourceList() + ); modules.Length.ShouldBe(2); modules[0].Type.ShouldBe(typeof(IndependentEmptyModule)); modules[1].Type.ShouldBe(typeof(MyStartupModule)); From 00a22cb0bb7ae337722129875a8ff2aa74ea86df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 5 Mar 2021 17:16:05 +0300 Subject: [PATCH 13/15] CmsKitHttpApiModule should not depend on applicatin layers. --- .../src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj | 4 ++-- .../Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj index 64a3dcef21..b23ef3ba0e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo.CmsKit.HttpApi.csproj @@ -9,9 +9,9 @@ - + - + diff --git a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs index c4a45bb8cf..219f2d9442 100644 --- a/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.HttpApi/Volo/CmsKit/CmsKitHttpApiModule.cs @@ -5,8 +5,8 @@ using Volo.CmsKit.Public; namespace Volo.CmsKit { [DependsOn( - typeof(CmsKitAdminApplicationModule), - typeof(CmsKitPublicApplicationModule), + typeof(CmsKitAdminHttpApiModule), + typeof(CmsKitPublicHttpApiModule), typeof(CmsKitApplicationContractsModule) )] public class CmsKitHttpApiModule : AbpModule From 460e38f6542d212e189731e7a769799cd92a65a7 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 7 Mar 2021 10:20:08 +0800 Subject: [PATCH 14/15] Make IInitLogger inherit ILogger. --- .../ServiceCollectionLoggingExtensions.cs | 9 +++--- .../Volo/Abp/AbpApplicationBase.cs | 18 +++++------ .../InternalServiceCollectionExtensions.cs | 6 ++-- .../Volo/Abp/Logging/AbpInitLogEntry.cs | 30 ++++++++----------- .../Volo/Abp/Logging/DefaultInitLogger.cs | 30 ++++++++++++++----- .../Volo/Abp/Logging/IInitLogger.cs | 12 ++------ .../Volo/Abp/Logging/IInitLoggerFactory.cs | 7 +++++ .../Volo/Abp/Logging/InitLoggerFactory.cs | 15 ++++++++++ .../Volo/Abp/Modularity/AbpModuleHelper.cs | 5 ++-- .../Volo/Abp/Modularity/ModuleLoader.cs | 13 ++++---- .../PlugIns/PlugInSourceExtensions.cs | 5 ++-- .../Modularity/PlugIns/PlugInSourceList.cs | 6 ++-- .../Volo/Abp/Modularity/ModuleLoader_Tests.cs | 4 +-- 13 files changed, 92 insertions(+), 68 deletions(-) create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Logging/InitLoggerFactory.cs diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs index 48921cb99b..e31e7cbf51 100644 --- a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs +++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionLoggingExtensions.cs @@ -1,12 +1,13 @@ -using Volo.Abp.Logging; +using Microsoft.Extensions.Logging; +using Volo.Abp.Logging; namespace Microsoft.Extensions.DependencyInjection { public static class ServiceCollectionLoggingExtensions { - public static IInitLogger GetInitLogger(this IServiceCollection services) + public static ILogger GetInitLogger(this IServiceCollection services) { - return services.GetSingletonInstance(); + return services.GetSingletonInstance().Create(); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 256a1dd05d..61cee2ce90 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -62,7 +62,7 @@ namespace Volo.Abp { //TODO: Shutdown if not done before? } - + protected virtual void SetServiceProvider(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; @@ -79,7 +79,7 @@ namespace Volo.Abp .InitializeModules(new ApplicationInitializationContext(scope.ServiceProvider)); } } - + protected virtual void WriteInitLogs(IServiceProvider serviceProvider) { var logger = serviceProvider.GetService>(); @@ -87,14 +87,14 @@ namespace Volo.Abp { return; } - - var initLogger = serviceProvider.GetRequiredService(); - + + var initLogger = serviceProvider.GetRequiredService().Create(); + foreach (var entry in initLogger.Entries) { - logger.LogWithLevel(entry.Level, entry.Message, entry.Exception); + logger.Log(entry.LogLevel, entry.EventId, entry.State, entry.Exception, entry.Formatter); } - + initLogger.Entries.Clear(); } @@ -108,7 +108,7 @@ namespace Volo.Abp options.PlugInSources ); } - + //TODO: We can extract a new class for this protected virtual void ConfigureServices() { @@ -179,4 +179,4 @@ namespace Volo.Abp } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs index c116a20080..476670b98c 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.Internal } internal static void AddCoreAbpServices(this IServiceCollection services, - IAbpApplication abpApplication, + IAbpApplication abpApplication, AbpApplicationCreationOptions applicationCreationOptions) { var moduleLoader = new ModuleLoader(); @@ -36,7 +36,7 @@ namespace Volo.Abp.Internal services.TryAddSingleton(moduleLoader); services.TryAddSingleton(assemblyFinder); services.TryAddSingleton(typeFinder); - services.TryAddSingleton(new DefaultInitLogger()); + services.TryAddSingleton(new InitLoggerFactory()); services.AddAssemblyOf(); @@ -49,4 +49,4 @@ namespace Volo.Abp.Internal }); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs index 17a346fa1c..da44f2be2b 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs @@ -1,26 +1,20 @@ using System; -using JetBrains.Annotations; using Microsoft.Extensions.Logging; namespace Volo.Abp.Logging { public class AbpInitLogEntry { - public LogLevel Level { get; } - - public string Message { get; } - - [CanBeNull] - public Exception Exception { get; } - - public AbpInitLogEntry( - LogLevel level, - string message, - Exception exception) - { - Level = level; - Message = message; - Exception = exception; - } + public LogLevel LogLevel { get; set; } + + public EventId EventId { get; set; } + + public object State { get; set; } + + public Exception Exception { get; set; } + + public Func Formatter { get; set; } + + public string Message => Formatter(State, Exception); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs index e1f7344f39..2cc0963282 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Logging; namespace Volo.Abp.Logging { - public class DefaultInitLogger : IInitLogger + public class DefaultInitLogger : IInitLogger { public List Entries { get; } @@ -12,13 +12,27 @@ namespace Volo.Abp.Logging { Entries = new List(); } - - public void Log( - LogLevel logLevel, - string message, - Exception exception = null) + + public virtual void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + Entries.Add(new AbpInitLogEntry + { + LogLevel = logLevel, + EventId = eventId, + State = state, + Exception = exception, + Formatter = (s, e) => formatter((TState)s, e), + }); + } + + public virtual bool IsEnabled(LogLevel logLevel) + { + return logLevel != LogLevel.None; + } + + public virtual IDisposable BeginScope(TState state) { - Entries.Add(new AbpInitLogEntry(logLevel, message, exception)); + return NullDisposable.Instance; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs index 5c549682e9..bcb578394f 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLogger.cs @@ -1,16 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.Extensions.Logging; namespace Volo.Abp.Logging { - public interface IInitLogger + public interface IInitLogger : ILogger { public List Entries { get; } - - void Log( - LogLevel logLevel, - string message, - Exception exception = null); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs new file mode 100644 index 0000000000..91300f7967 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Logging +{ + public interface IInitLoggerFactory + { + IInitLogger Create(); + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/InitLoggerFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/InitLoggerFactory.cs new file mode 100644 index 0000000000..89005bee31 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/InitLoggerFactory.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.Logging +{ + public class InitLoggerFactory : IInitLoggerFactory + { + private readonly Dictionary _cache = new Dictionary(); + + public virtual IInitLogger Create() + { + return (IInitLogger)_cache.GetOrAdd(typeof(T), () => new DefaultInitLogger());; + } + } +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs index 9331014623..e8bccb8e18 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs @@ -3,13 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.Extensions.Logging; -using Volo.Abp.Logging; namespace Volo.Abp.Modularity { internal static class AbpModuleHelper { - public static List FindAllModuleTypes(Type startupModuleType, IInitLogger logger) + public static List FindAllModuleTypes(Type startupModuleType, ILogger logger) { var moduleTypes = new List(); logger.Log(LogLevel.Information, "Loaded ABP modules:"); @@ -41,7 +40,7 @@ namespace Volo.Abp.Modularity private static void AddModuleAndDependenciesResursively( List moduleTypes, Type moduleType, - IInitLogger logger, + ILogger logger, int depth = 0) { AbpModule.CheckAbpModuleType(moduleType); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs index 56ee2f5d71..3c5fb9aa56 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/ModuleLoader.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Logging; using Volo.Abp.Modularity.PlugIns; namespace Volo.Abp.Modularity @@ -26,7 +25,7 @@ namespace Volo.Abp.Modularity } private List GetDescriptors( - IServiceCollection services, + IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources) { @@ -44,16 +43,16 @@ namespace Volo.Abp.Modularity Type startupModuleType, PlugInSourceList plugInSources) { - var initLogger = services.GetInitLogger(); - + var logger = services.GetInitLogger(); + //All modules starting from the startup module - foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType, initLogger)) + foreach (var moduleType in AbpModuleHelper.FindAllModuleTypes(startupModuleType, logger)) { modules.Add(CreateModuleDescriptor(services, moduleType)); } //Plugin modules - foreach (var moduleType in plugInSources.GetAllModules(initLogger)) + foreach (var moduleType in plugInSources.GetAllModules(logger)) { if (modules.Any(m => m.Type == moduleType)) { @@ -105,4 +104,4 @@ namespace Volo.Abp.Modularity } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs index b041cd160d..92be156b69 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using JetBrains.Annotations; +using Microsoft.Extensions.Logging; using Volo.Abp.Logging; namespace Volo.Abp.Modularity.PlugIns @@ -8,7 +9,7 @@ namespace Volo.Abp.Modularity.PlugIns public static class PlugInSourceExtensions { [NotNull] - public static Type[] GetModulesWithAllDependencies([NotNull] this IPlugInSource plugInSource, IInitLogger logger) + public static Type[] GetModulesWithAllDependencies([NotNull] this IPlugInSource plugInSource, ILogger logger) { Check.NotNull(plugInSource, nameof(plugInSource)); @@ -19,4 +20,4 @@ namespace Volo.Abp.Modularity.PlugIns .ToArray(); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs index 1d5509b359..06c0187a32 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Modularity/PlugIns/PlugInSourceList.cs @@ -2,14 +2,14 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; -using Volo.Abp.Logging; +using Microsoft.Extensions.Logging; namespace Volo.Abp.Modularity.PlugIns { public class PlugInSourceList : List { [NotNull] - internal Type[] GetAllModules(IInitLogger logger) + internal Type[] GetAllModules(ILogger logger) { return this .SelectMany(pluginSource => pluginSource.GetModulesWithAllDependencies(logger)) @@ -17,4 +17,4 @@ namespace Volo.Abp.Modularity.PlugIns .ToArray(); } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs index cc0117e184..4d45888eb3 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Modularity var moduleLoader = new ModuleLoader(); var modules = moduleLoader.LoadModules( new ServiceCollection() - .AddSingleton(new DefaultInitLogger()), + .AddSingleton(new InitLoggerFactory()), typeof(MyStartupModule), new PlugInSourceList() ); @@ -28,7 +28,7 @@ namespace Volo.Abp.Modularity { public override void ConfigureServices(ServiceConfigurationContext context) { - + } } } From e756fac8c56d5f2cf23db9742a2b7bd5bc650213 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 7 Mar 2021 10:29:28 +0800 Subject: [PATCH 15/15] Rename InitLoggerFactory to DefaultInitLoggerFactory. --- .../Volo/Abp/Internal/InternalServiceCollectionExtensions.cs | 2 +- .../{InitLoggerFactory.cs => DefaultInitLoggerFactory.cs} | 2 +- .../Volo/Abp/Modularity/ModuleLoader_Tests.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename framework/src/Volo.Abp.Core/Volo/Abp/Logging/{InitLoggerFactory.cs => DefaultInitLoggerFactory.cs} (84%) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs index 476670b98c..ee06003204 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/InternalServiceCollectionExtensions.cs @@ -36,7 +36,7 @@ namespace Volo.Abp.Internal services.TryAddSingleton(moduleLoader); services.TryAddSingleton(assemblyFinder); services.TryAddSingleton(typeFinder); - services.TryAddSingleton(new InitLoggerFactory()); + services.TryAddSingleton(new DefaultInitLoggerFactory()); services.AddAssemblyOf(); diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/InitLoggerFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLoggerFactory.cs similarity index 84% rename from framework/src/Volo.Abp.Core/Volo/Abp/Logging/InitLoggerFactory.cs rename to framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLoggerFactory.cs index 89005bee31..cb2e5d4060 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/InitLoggerFactory.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLoggerFactory.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Volo.Abp.Logging { - public class InitLoggerFactory : IInitLoggerFactory + public class DefaultInitLoggerFactory : IInitLoggerFactory { private readonly Dictionary _cache = new Dictionary(); diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs index 4d45888eb3..4b7ed95e89 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Modularity var moduleLoader = new ModuleLoader(); var modules = moduleLoader.LoadModules( new ServiceCollection() - .AddSingleton(new InitLoggerFactory()), + .AddSingleton(new DefaultInitLoggerFactory()), typeof(MyStartupModule), new PlugInSourceList() );