From ead4e9404ede7c654c0e56e23d8c26f5faacc96c Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Sat, 8 Oct 2022 18:07:23 +0800 Subject: [PATCH 01/38] feat: Add Globalization --- Masa.Framework.sln | 28 +++++++++++++++++++ .../IMasaStringLocalizer.cs | 27 ++++++++++++++++++ .../LanguageInfo.cs | 11 ++++++++ ...ngBlocks.Globalization.Localization.csproj | 13 +++++++++ .../Options/MasaLocalizationOptions.cs | 11 ++++++++ .../_Imports.cs | 3 ++ ...BuildingBlocks.Globalization.Timing.csproj | 9 ++++++ .../_Imports.cs | 3 ++ 8 files changed, 105 insertions(+) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 710ac7ac1..88bf4d3bc 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -567,6 +567,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Authentication EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Authentication.OpenIdConnect.Cache.Storage.Tests", "src\Contrib\Authentication\OpenIdConnect\Tests\Masa.Contrib.Authentication.OpenIdConnect.Cache.Storage.Tests\Masa.Contrib.Authentication.OpenIdConnect.Cache.Storage.Tests.csproj", "{0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalization", "{D10FC534-0091-42B4-809F-82C1E2164ED5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalization", "{5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.Localization", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.Localization\Masa.BuildingBlocks.Globalization.Localization.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.Timing", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.Timing\Masa.BuildingBlocks.Globalization.Timing.csproj", "{548318DB-8655-421C-901A-B1A6BDC05962}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2015,6 +2023,22 @@ Global {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8}.Release|Any CPU.Build.0 = Release|Any CPU {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8}.Release|x64.ActiveCfg = Release|Any CPU {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8}.Release|x64.Build.0 = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.Build.0 = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.Build.0 = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.ActiveCfg = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.Build.0 = Release|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|Any CPU.Build.0 = Debug|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|x64.ActiveCfg = Debug|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|x64.Build.0 = Debug|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Release|Any CPU.ActiveCfg = Release|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Release|Any CPU.Build.0 = Release|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Release|x64.ActiveCfg = Release|Any CPU + {548318DB-8655-421C-901A-B1A6BDC05962}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2294,6 +2318,10 @@ Global {C0E2763D-13C8-432F-8628-42BFAF57F0FF} = {3198630F-C09B-40AE-B9A1-E79249296E48} {B4E3A1D7-371D-4B0B-A140-94B4F1C23435} = {59BC0E0F-ECEF-4D40-81EC-0EE51CCF9070} {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8} = {59BC0E0F-ECEF-4D40-81EC-0EE51CCF9070} + {D10FC534-0091-42B4-809F-82C1E2164ED5} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} + {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} + {AC84401A-58FD-4786-9E10-BA99D17ABB3E} = {D10FC534-0091-42B4-809F-82C1E2164ED5} + {548318DB-8655-421C-901A-B1A6BDC05962} = {D10FC534-0091-42B4-809F-82C1E2164ED5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs new file mode 100644 index 000000000..06651218f --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs @@ -0,0 +1,27 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public interface IMasaStringLocalizer +{ + /// Gets the string resource with the given name. + /// The name of the string resource. + /// The string resource as a . + LocalizedString this[string name] { get; } + + /// + /// Gets the string resource with the given name and formatted with the supplied arguments. + /// + /// The name of the string resource. + /// The values to format the string with. + /// The formatted string resource as a . + LocalizedString this[string name, params object[] arguments] { get; } + + /// Gets all string resources. + /// + /// A indicating whether to include strings from parent cultures. + /// + /// The strings. + IEnumerable GetAllStrings(bool includeParentCultures); +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs new file mode 100644 index 000000000..1b94e62ce --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public class LanguageInfo +{ + string CultureName { get; } + + string DisplayName { get; } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj new file mode 100644 index 000000000..64b857c32 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs new file mode 100644 index 000000000..6c2c460d4 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public class MasaLocalizationOptions +{ + public Type DefaultResourceType { get; set; } + + public List Languages { get; set; } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs new file mode 100644 index 000000000..c84eb7856 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs @@ -0,0 +1,3 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj new file mode 100644 index 000000000..eb2460e91 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs new file mode 100644 index 000000000..c84eb7856 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs @@ -0,0 +1,3 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + From 9398da4dead3e70e55e6b7a1f5fc7765e4be5cee Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Tue, 11 Oct 2022 20:43:26 +0800 Subject: [PATCH 02/38] feat: Add Localization --- Masa.Framework.sln | 11 ++++ ...FileLocalizationResourceContributorBase.cs | 33 ++++++++++ .../ILocalizationResourceContributor.cs | 14 ++++ .../LocalizationResource.cs | 29 +++++++++ .../LocalizationResourceContributorBase.cs | 40 ++++++++++++ .../LocalizationResourceDictionary.cs | 30 +++++++++ .../Options/MasaLocalizationOptions.cs | 9 +++ .../_Imports.cs | 1 + ...JsonFileLocalizationResourceContributor.cs | 65 +++++++++++++++++++ .../Json/JsonLocalizationFile.cs | 20 ++++++ ....Contrib.Globalization.Localization.csproj | 14 ++++ .../_Imports.cs | 6 ++ 12 files changed, 272 insertions(+) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 88bf4d3bc..eef423fb8 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -575,6 +575,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globali EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.Timing", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.Timing\Masa.BuildingBlocks.Globalization.Timing.csproj", "{548318DB-8655-421C-901A-B1A6BDC05962}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization", "src\Contrib\Globalization\Masa.Contrib.Globalization.Localization\Masa.Contrib.Globalization.Localization.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2039,6 +2041,14 @@ Global {548318DB-8655-421C-901A-B1A6BDC05962}.Release|Any CPU.Build.0 = Release|Any CPU {548318DB-8655-421C-901A-B1A6BDC05962}.Release|x64.ActiveCfg = Release|Any CPU {548318DB-8655-421C-901A-B1A6BDC05962}.Release|x64.Build.0 = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|x64.ActiveCfg = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|x64.Build.0 = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|Any CPU.Build.0 = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.ActiveCfg = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2322,6 +2332,7 @@ Global {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} {AC84401A-58FD-4786-9E10-BA99D17ABB3E} = {D10FC534-0091-42B4-809F-82C1E2164ED5} {548318DB-8655-421C-901A-B1A6BDC05962} = {D10FC534-0091-42B4-809F-82C1E2164ED5} + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs new file mode 100644 index 000000000..a095df5eb --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public abstract class FileLocalizationResourceContributorBase : LocalizationResourceContributorBase +{ + private readonly string _filePath; + private readonly ILogger? _logger; + + public FileLocalizationResourceContributorBase(Type resourceType, + string cultureName, + string filePath, + ILoggerFactory? loggerFactory) : base(resourceType, cultureName) + { + _filePath = filePath; + _logger = loggerFactory?.CreateLogger(); + } + + protected override Dictionary GetDictionaries() + { + var fileContent = File.ReadAllText(_filePath); + if (string.IsNullOrWhiteSpace(fileContent)) + { + _logger?.LogWarning("File content is empty, the file is {file}", _filePath); + return new Dictionary(); + } + + return ParseResourceFromFileContent(fileContent); + } + + protected abstract Dictionary ParseResourceFromFileContent(string fileContent); +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs new file mode 100644 index 000000000..6bf7723db --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs @@ -0,0 +1,14 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +/// +/// 具体资源类下具体语言的资源 +/// +public interface ILocalizationResourceContributor +{ + LocalizedString? GetOrNull(string name); + + void ResetResource(); +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs new file mode 100644 index 000000000..e39e574ac --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs @@ -0,0 +1,29 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public class LocalizationResource +{ + /// + /// 语言、内容集合 + /// + private Dictionary _dictionary { get; } + + public Type ResourceType { get; } + + public string? DefaultCultureName { get; } + + // /// + // /// 用于获取父类的key、value + // /// + // public List BaseResourceTypes { get; set; } + + public LocalizationResource(Type resourceType, string? defaultCultureName) + { + _dictionary = new(); + ResourceType = resourceType; + DefaultCultureName = defaultCultureName; + // BaseResourceTypes = new(); + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs new file mode 100644 index 000000000..91aa3845f --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs @@ -0,0 +1,40 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public abstract class LocalizationResourceContributorBase : ILocalizationResourceContributor +{ + private Dictionary? _dictionaries; + + public Type ResourceType { get; } + + public string CultureName { get; } + + public LocalizationResourceContributorBase(Type resourceType, string cultureName) + { + ResourceType = resourceType; + CultureName = cultureName; + } + + public LocalizedString? GetOrNull(string name) + { + _dictionaries ??= GetDictionaries(); + return GetOrNull(_dictionaries, name); + } + + protected abstract Dictionary GetDictionaries(); + + protected virtual LocalizedString? GetOrNull(Dictionary dictionaries, string name) + { + if (dictionaries.TryGetValue(name, out LocalizedString? value)) + return value; + + return null; + } + + public virtual void ResetResource() + { + _dictionaries = null; + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs new file mode 100644 index 000000000..2b3af523a --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs @@ -0,0 +1,30 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public class LocalizationResourceDictionary : Dictionary +{ + public LocalizationResource Add(string? defaultCultureName = null) + { + return Add(typeof(TResource), defaultCultureName); + } + + public LocalizationResource Add(Type resourceType, string? defaultCultureName = null) + { + if (ContainsKey(resourceType)) + throw new Exception("This resource is already added before: " + resourceType.FullName); + + return this[resourceType] = new LocalizationResource(resourceType, defaultCultureName); + } + + public LocalizationResource Get() + { + var resourceType = typeof(TResource); + + if (!ContainsKey(resourceType)) + throw new Exception("Can not find a resource with given type: " + resourceType.FullName); + + return this[resourceType]; + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs index 6c2c460d4..521963be0 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs @@ -5,7 +5,16 @@ namespace Microsoft.Extensions.Localization; public class MasaLocalizationOptions { + public string DefaultCultureName { get; set; } + public Type DefaultResourceType { get; set; } public List Languages { get; set; } + + public LocalizationResourceDictionary Resources { get; } + + public MasaLocalizationOptions() + { + Resources = new (); + } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs index c84eb7856..4c9670544 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs @@ -1,3 +1,4 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Microsoft.Extensions.Logging; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs new file mode 100644 index 000000000..75ccea552 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs @@ -0,0 +1,65 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization; + +public class JsonFileLocalizationResourceContributor : FileLocalizationResourceContributorBase +{ + private readonly JsonSerializerOptions _deserializeOptions; + + public JsonFileLocalizationResourceContributor( + Type resourceType, + string cultureName, + string filePath, + JsonSerializerOptions deserializeOptions, + ILoggerFactory? loggerFactory) : base(resourceType, cultureName, filePath, loggerFactory) + { + _deserializeOptions = deserializeOptions; + } + + protected override Dictionary ParseResourceFromFileContent(string fileContent) + { + JsonLocalizationFile jsonFile; + try + { + jsonFile = JsonSerializer.Deserialize(fileContent, _deserializeOptions) ?? + throw new UserFriendlyException($"Can not parse json string. json file path: {fileContent}"); + } + catch (JsonException ex) + { + throw new UserFriendlyException("Can not parse json string. " + ex.Message); + } + var cultureCode = jsonFile.Culture; + if (string.IsNullOrEmpty(cultureCode)) + { + throw new UserFriendlyException("Culture is empty in language json file."); + } + + var dictionary = new Dictionary(); + var duplicateNames = new List(); + foreach (var item in jsonFile.Texts) + { + if (string.IsNullOrEmpty(item.Key)) + { + throw new UserFriendlyException("The key is empty in given json string."); + } + + if (dictionary.ContainsKey(item.Key)) + { + duplicateNames.Add(item.Key); + } + + dictionary[item.Key] = new LocalizedString(item.Key, + item.Value.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", Environment.NewLine)); + } + + if (duplicateNames.Count > 0) + { + throw new UserFriendlyException( + "A dictionary can not contain same key twice. There are some duplicated names: " + + string.Join(", ", duplicateNames)); + } + + return dictionary; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs new file mode 100644 index 000000000..4a75ba7cc --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization; + +public class JsonLocalizationFile +{ + /// + /// Culture name + /// eg: en,en-us, zh-CN + /// + public string Culture { get; set; } + + public Dictionary Texts { get; set; } + + public JsonLocalizationFile() + { + Texts = new Dictionary(); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj new file mode 100644 index 000000000..671f6bff2 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs new file mode 100644 index 000000000..58d9fc192 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Microsoft.Extensions.Localization; +global using Microsoft.Extensions.Logging; +global using System.Text.Json; From 3834f69459a4646a9c43256934e46d9e966b661f Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 12 Oct 2022 21:06:13 +0800 Subject: [PATCH 03/38] fix: Fix Localization --- Masa.Framework.sln | 14 +++++ ...FileLocalizationResourceContributorBase.cs | 11 ++-- .../ILocalizationResourceContributor.cs | 2 + .../LocalizationResource.cs | 19 +++---- .../LocalizationResourceContributorBase.cs | 14 +++-- ...ngBlocks.Globalization.Localization.csproj | 4 ++ ...JsonFileLocalizationResourceContributor.cs | 8 +-- .../LocalizationResourceExtensions.cs | 55 +++++++++++++++++++ ....Contrib.Globalization.Localization.csproj | 1 + .../_Imports.cs | 3 + .../LocalizationResource.cs | 9 +++ ...ib.Globalization.Localization.Tests.csproj | 33 +++++++++++ 12 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 6bbdfe0e1..1eb576664 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -585,6 +585,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Service.Caller EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization", "src\Contrib\Globalization\Masa.Contrib.Globalization.Localization\Masa.Contrib.Globalization.Localization.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D2E598D5-5E44-4275-AF03-4BAD07A0E13B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.Localization.Tests\Masa.Contrib.Globalization.Localization.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2073,6 +2077,14 @@ Global {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|Any CPU.Build.0 = Release|Any CPU {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.ActiveCfg = Release|Any CPU {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.Build.0 = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|x64.ActiveCfg = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|x64.Build.0 = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|Any CPU.Build.0 = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.ActiveCfg = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2361,6 +2373,8 @@ Global {8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02} = {8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A} {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {6C732EBE-22CC-4160-B427-F4558C899024} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs index a095df5eb..9f014772b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs @@ -9,25 +9,24 @@ public abstract class FileLocalizationResourceContributorBase : LocalizationReso private readonly ILogger? _logger; public FileLocalizationResourceContributorBase(Type resourceType, - string cultureName, string filePath, - ILoggerFactory? loggerFactory) : base(resourceType, cultureName) + ILoggerFactory? loggerFactory) : base(resourceType) { _filePath = filePath; _logger = loggerFactory?.CreateLogger(); } - protected override Dictionary GetDictionaries() + protected override (string CultureName, Dictionary Dictionary) GetCultureNameAndDictionaries() { var fileContent = File.ReadAllText(_filePath); if (string.IsNullOrWhiteSpace(fileContent)) { _logger?.LogWarning("File content is empty, the file is {file}", _filePath); - return new Dictionary(); + return new("", new Dictionary()); } - return ParseResourceFromFileContent(fileContent); + return ParseCultureNameAndResourceFromFileContent(fileContent); } - protected abstract Dictionary ParseResourceFromFileContent(string fileContent); + protected abstract (string CultureName, Dictionary Dictionary) ParseCultureNameAndResourceFromFileContent(string fileContent); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs index 6bf7723db..a97a46f9e 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs @@ -8,6 +8,8 @@ namespace Microsoft.Extensions.Localization; /// public interface ILocalizationResourceContributor { + string CultureName { get; } + LocalizedString? GetOrNull(string name); void ResetResource(); diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs index e39e574ac..c52495386 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs @@ -5,25 +5,24 @@ namespace Microsoft.Extensions.Localization; public class LocalizationResource { - /// - /// 语言、内容集合 - /// - private Dictionary _dictionary { get; } + private List _dictionary { get; } public Type ResourceType { get; } public string? DefaultCultureName { get; } - // /// - // /// 用于获取父类的key、value - // /// - // public List BaseResourceTypes { get; set; } - public LocalizationResource(Type resourceType, string? defaultCultureName) { _dictionary = new(); ResourceType = resourceType; DefaultCultureName = defaultCultureName; - // BaseResourceTypes = new(); + } + + public void AddContributor(ILocalizationResourceContributor localizationResourceContributor) + { + if (_dictionary.Any(d => d.CultureName.Equals(localizationResourceContributor.CultureName, StringComparison.OrdinalIgnoreCase))) + throw new Exception($"The {localizationResourceContributor.CultureName} already exists with {ResourceType.FullName}"); + + _dictionary.Add(localizationResourceContributor); } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs index 91aa3845f..e52ac7429 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs @@ -9,21 +9,25 @@ public abstract class LocalizationResourceContributorBase : ILocalizationResourc public Type ResourceType { get; } - public string CultureName { get; } + public string CultureName { get; protected set; } - public LocalizationResourceContributorBase(Type resourceType, string cultureName) + public LocalizationResourceContributorBase(Type resourceType) { ResourceType = resourceType; - CultureName = cultureName; } public LocalizedString? GetOrNull(string name) { - _dictionaries ??= GetDictionaries(); + if (_dictionaries == null) + { + var item = GetCultureNameAndDictionaries(); + CultureName = item.CultureName; + _dictionaries = item.Dictionary; + } return GetOrNull(_dictionaries, name); } - protected abstract Dictionary GetDictionaries(); + protected abstract (string CultureName, Dictionary Dictionary) GetCultureNameAndDictionaries(); protected virtual LocalizedString? GetOrNull(Dictionary dictionaries, string name) { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj index 64b857c32..64d9650fb 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs index 75ccea552..3198e0635 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs @@ -9,15 +9,15 @@ public class JsonFileLocalizationResourceContributor : FileLocalizationResourceC public JsonFileLocalizationResourceContributor( Type resourceType, - string cultureName, string filePath, JsonSerializerOptions deserializeOptions, - ILoggerFactory? loggerFactory) : base(resourceType, cultureName, filePath, loggerFactory) + ILoggerFactory? loggerFactory) : base(resourceType, filePath, loggerFactory) { _deserializeOptions = deserializeOptions; } - protected override Dictionary ParseResourceFromFileContent(string fileContent) + protected override (string CultureName, Dictionary Dictionary) ParseCultureNameAndResourceFromFileContent( + string fileContent) { JsonLocalizationFile jsonFile; try @@ -60,6 +60,6 @@ protected override Dictionary ParseResourceFromFileCont string.Join(", ", duplicateNames)); } - return dictionary; + return new(jsonFile.Culture, dictionary); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs new file mode 100644 index 000000000..c66c75982 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs @@ -0,0 +1,55 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization; + +public static class LocalizationResourceExtensions +{ + private static readonly string _baseDirectory = AppDomain.CurrentDomain.BaseDirectory; + private static ILoggerFactory? _loggerFactory; + + public static LocalizationResource AddJson( + this LocalizationResource localizationResource, + string languageDirectory, + JsonSerializerOptions deserializeOptions) + { + languageDirectory.CheckIsNullOrWhiteSpace(); + + if (!Directory.Exists(languageDirectory)) + { + var path = Path.Combine(_baseDirectory, languageDirectory); + if (!Directory.Exists(path)) + { + throw new UserFriendlyException($"[{languageDirectory}] does not exist"); + } + } + + var resources = GetResources(localizationResource, languageDirectory, deserializeOptions); + foreach (var resource in resources) + { + localizationResource.AddContributor(resource); + } + + return localizationResource; + } + + public static List GetResources( + LocalizationResource localizationResource, + string languageDirectory, + JsonSerializerOptions deserializeOptions) + { + var files = Directory.GetFiles(languageDirectory).ToList(); + + _loggerFactory ??= MasaApp.GetServices().BuildServiceProvider().GetService(); + + return files.Select + (file => (ILocalizationResourceContributor)new JsonFileLocalizationResourceContributor + ( + localizationResource.ResourceType, + file, + deserializeOptions, _loggerFactory + ) + ) + .ToList(); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj index 671f6bff2..93e9575a4 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs index 58d9fc192..a902f868c 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs @@ -3,4 +3,7 @@ global using Microsoft.Extensions.Localization; global using Microsoft.Extensions.Logging; +global using System.Reflection; global using System.Text.Json; +global using Masa.BuildingBlocks.Data; +global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs new file mode 100644 index 000000000..9451a0721 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization.Tests; + +public class LocalizationResource +{ + +} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj new file mode 100644 index 000000000..2f70b9e94 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj @@ -0,0 +1,33 @@ + + + + net6.0 + enable + false + enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + From 4e2c7922bc898a763b4afe61d3f533a7aa70ace3 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 17 Oct 2022 23:36:06 +0800 Subject: [PATCH 04/38] feat(Localization): Add Localization --- Masa.Framework.sln | 11 +++ Masa.Framework.sln.DotSettings | 2 + .../Extensions/ConfigurationExtensions.cs | 40 +++++++++ ...FileLocalizationResourceContributorBase.cs | 32 ------- .../ILocalizationResourceContributor.cs | 7 +- .../IMasaStringLocalizer.cs | 11 +-- .../IMasaStringLocalizerFactory.cs | 11 +++ .../IMasaStringLocalizerOfT.cs | 9 ++ .../LocalizationResource.cs | 20 +++-- .../LocalizationResourceContributorBase.cs | 44 --------- .../LocalizationResourceDictionary.cs | 9 +- .../MasaStringLocalizerFactory.cs | 23 +++++ .../Options/MasaLocalizationOptions.cs | 8 ++ .../_Imports.cs | 5 +- .../Extensions/ServiceCollectionExtensions.cs | 6 +- .../LocalMasaConfigurationRepository.cs | 27 +----- .../DccLocalizationResourceContributor.cs | 26 ++++++ ...trib.Globalization.Localization.Dcc.csproj | 14 +++ .../_Imports.cs | 6 ++ .../DefaultResource.cs} | 4 +- .../Extensions/ServiceCollectionExtensions.cs | 24 +++++ .../FileLocalizationConfigurationProvider.cs | 89 +++++++++++++++++++ .../Internal/Const.cs | 14 +++ .../LocalizationResourceConfiguration.cs | 9 ++ ...JsonFileLocalizationResourceContributor.cs | 65 -------------- .../JsonLocalizationConfigurationProvider.cs | 20 +++++ .../JsonLocalizationConfigurationSource.cs | 26 ++++++ .../Json/JsonLocalizationFile.cs | 20 ----- .../LocalLocalizationResourceContributor.cs | 34 +++++++ .../LocalizationResourceExtensions.cs | 58 +++++++++--- ....Contrib.Globalization.Localization.csproj | 1 + .../MasaStringLocalizerOfT.cs | 54 +++++++++++ .../_Imports.cs | 12 ++- .../LocalizationResourceTest.cs | 82 +++++++++++++++++ ...ib.Globalization.Localization.Tests.csproj | 10 ++- .../Resources/en.json | 6 ++ .../Resources/zh-Cn.json | 6 ++ .../_Imports.cs | 8 ++ 38 files changed, 619 insertions(+), 234 deletions(-) create mode 100644 src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs rename src/Contrib/Globalization/{Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs => Masa.Contrib.Globalization.Localization/DefaultResource.cs} (63%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 1eb576664..0f9615638 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -589,6 +589,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D2E598D5 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.Localization.Tests\Masa.Contrib.Globalization.Localization.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.Localization.Dcc\Masa.Contrib.Globalization.Localization.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2085,6 +2087,14 @@ Global {6C732EBE-22CC-4160-B427-F4558C899024}.Release|Any CPU.Build.0 = Release|Any CPU {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.ActiveCfg = Release|Any CPU {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.Build.0 = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|x64.ActiveCfg = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|x64.Build.0 = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|Any CPU.Build.0 = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.ActiveCfg = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2375,6 +2385,7 @@ Global {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} {6C732EBE-22CC-4160-B427-F4558C899024} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} + {B0EFDF9E-81FF-4880-992B-8A65A2008717} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/Masa.Framework.sln.DotSettings b/Masa.Framework.sln.DotSettings index d36e65e1f..85260b77e 100644 --- a/Masa.Framework.sln.DotSettings +++ b/Masa.Framework.sln.DotSettings @@ -1,2 +1,4 @@  + True + True True \ No newline at end of file diff --git a/src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs b/src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs new file mode 100644 index 000000000..a2f8e8f4b --- /dev/null +++ b/src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs @@ -0,0 +1,40 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.DependencyInjection; + +public static class ConfigurationExtensions +{ + public static Dictionary ConvertToDictionary(this IConfiguration configuration) + { + var data = new Dictionary(); + GetData(configuration, configuration.GetChildren(), ref data); + return data; + } + + private static void GetData( + IConfiguration configuration, + IEnumerable configurationSections, + ref Dictionary dictionary) + { + foreach (var configurationSection in configurationSections) + { + var section = configuration.GetSection(configurationSection.Path); + + var childrenSections = section.GetChildren()?.ToList() ?? new List(); + + if (!section.Exists() || !childrenSections.Any()) + { + var key = section.Path; + if (!dictionary.ContainsKey(key)) + { + dictionary.Add(key, configuration[section.Path]); + } + } + else + { + GetData(configuration, childrenSections, ref dictionary); + } + } + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs deleted file mode 100644 index 9f014772b..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/FileLocalizationResourceContributorBase.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Microsoft.Extensions.Localization; - -public abstract class FileLocalizationResourceContributorBase : LocalizationResourceContributorBase -{ - private readonly string _filePath; - private readonly ILogger? _logger; - - public FileLocalizationResourceContributorBase(Type resourceType, - string filePath, - ILoggerFactory? loggerFactory) : base(resourceType) - { - _filePath = filePath; - _logger = loggerFactory?.CreateLogger(); - } - - protected override (string CultureName, Dictionary Dictionary) GetCultureNameAndDictionaries() - { - var fileContent = File.ReadAllText(_filePath); - if (string.IsNullOrWhiteSpace(fileContent)) - { - _logger?.LogWarning("File content is empty, the file is {file}", _filePath); - return new("", new Dictionary()); - } - - return ParseCultureNameAndResourceFromFileContent(fileContent); - } - - protected abstract (string CultureName, Dictionary Dictionary) ParseCultureNameAndResourceFromFileContent(string fileContent); -} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs index a97a46f9e..ed0757cd9 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs @@ -3,14 +3,9 @@ namespace Microsoft.Extensions.Localization; -/// -/// 具体资源类下具体语言的资源 -/// public interface ILocalizationResourceContributor { string CultureName { get; } - LocalizedString? GetOrNull(string name); - - void ResetResource(); + string? GetOrNull(string name); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs index 06651218f..ad03813da 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs @@ -8,7 +8,7 @@ public interface IMasaStringLocalizer /// Gets the string resource with the given name. /// The name of the string resource. /// The string resource as a . - LocalizedString this[string name] { get; } + string this[string name] { get; } /// /// Gets the string resource with the given name and formatted with the supplied arguments. @@ -16,12 +16,5 @@ public interface IMasaStringLocalizer /// The name of the string resource. /// The values to format the string with. /// The formatted string resource as a . - LocalizedString this[string name, params object[] arguments] { get; } - - /// Gets all string resources. - /// - /// A indicating whether to include strings from parent cultures. - /// - /// The strings. - IEnumerable GetAllStrings(bool includeParentCultures); + string this[string name, params object[] arguments] { get; } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs new file mode 100644 index 000000000..3a48d3a95 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public interface IMasaStringLocalizerFactory +{ + IMasaStringLocalizer Create(); + + IMasaStringLocalizer Create(Type resourceSource); +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs new file mode 100644 index 000000000..32612e177 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public interface IMasaStringLocalizer : IMasaStringLocalizer +{ + +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs index c52495386..a8c75b531 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs @@ -5,24 +5,34 @@ namespace Microsoft.Extensions.Localization; public class LocalizationResource { - private List _dictionary { get; } + private Dictionary _dictionary { get; } public Type ResourceType { get; } - public string? DefaultCultureName { get; } + public string? DefaultCultureName { get; internal set; } public LocalizationResource(Type resourceType, string? defaultCultureName) { - _dictionary = new(); + _dictionary = new(StringComparer.OrdinalIgnoreCase); ResourceType = resourceType; DefaultCultureName = defaultCultureName; } public void AddContributor(ILocalizationResourceContributor localizationResourceContributor) { - if (_dictionary.Any(d => d.CultureName.Equals(localizationResourceContributor.CultureName, StringComparison.OrdinalIgnoreCase))) + if (_dictionary.Any(d => d.Key.Equals(localizationResourceContributor.CultureName, StringComparison.OrdinalIgnoreCase))) throw new Exception($"The {localizationResourceContributor.CultureName} already exists with {ResourceType.FullName}"); - _dictionary.Add(localizationResourceContributor); + _dictionary.Add(localizationResourceContributor.CultureName, localizationResourceContributor); + } + + public ILocalizationResourceContributor? GetResourceContributor(CultureInfo? cultureInfo = null) + { + var cultureName = cultureInfo?.Name ?? CultureInfo.CurrentUICulture.Name; + + if (_dictionary.ContainsKey(cultureName)) + return _dictionary[cultureName]; + + return null; } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs deleted file mode 100644 index e52ac7429..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceContributorBase.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Microsoft.Extensions.Localization; - -public abstract class LocalizationResourceContributorBase : ILocalizationResourceContributor -{ - private Dictionary? _dictionaries; - - public Type ResourceType { get; } - - public string CultureName { get; protected set; } - - public LocalizationResourceContributorBase(Type resourceType) - { - ResourceType = resourceType; - } - - public LocalizedString? GetOrNull(string name) - { - if (_dictionaries == null) - { - var item = GetCultureNameAndDictionaries(); - CultureName = item.CultureName; - _dictionaries = item.Dictionary; - } - return GetOrNull(_dictionaries, name); - } - - protected abstract (string CultureName, Dictionary Dictionary) GetCultureNameAndDictionaries(); - - protected virtual LocalizedString? GetOrNull(Dictionary dictionaries, string name) - { - if (dictionaries.TryGetValue(name, out LocalizedString? value)) - return value; - - return null; - } - - public virtual void ResetResource() - { - _dictionaries = null; - } -} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs index 2b3af523a..9967a7ecf 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs @@ -18,13 +18,14 @@ public LocalizationResource Add(Type resourceType, string? defaultCultureName = return this[resourceType] = new LocalizationResource(resourceType, defaultCultureName); } - public LocalizationResource Get() + public LocalizationResource? GetOrNull(Type resourceType) { - var resourceType = typeof(TResource); - if (!ContainsKey(resourceType)) - throw new Exception("Can not find a resource with given type: " + resourceType.FullName); + return null; return this[resourceType]; } + + public LocalizationResource? GetOrNull() + => GetOrNull(typeof(TResource)); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs new file mode 100644 index 000000000..1dbad59af --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs @@ -0,0 +1,23 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public class MasaStringLocalizerFactory : IMasaStringLocalizerFactory +{ + private readonly IServiceProvider _serviceProvider; + + public MasaStringLocalizerFactory(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public IMasaStringLocalizer Create() + => _serviceProvider.GetRequiredService>(); + + public IMasaStringLocalizer Create(Type resourceSource) + { + var serviceType = typeof(IMasaStringLocalizer<>).MakeGenericType(resourceSource); + return (IMasaStringLocalizer)_serviceProvider.GetRequiredService(serviceType); + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs index 521963be0..eeea604a2 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs @@ -17,4 +17,12 @@ public MasaLocalizationOptions() { Resources = new (); } + + public void FormatResources() + { + foreach (var resource in Resources) + { + resource.Value.DefaultCultureName ??= DefaultCultureName; + } + } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs index 4c9670544..97f7f6b77 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs @@ -1,4 +1,5 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Microsoft.Extensions.Logging; +global using Microsoft.Extensions.DependencyInjection; +global using System.Globalization; diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs index c5bb62fb7..067d57562 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs @@ -136,7 +136,11 @@ public static IServiceCollection AddMasaConfiguration( configurationBuilder.AddConfiguration(masaConfiguration); if (sourceConfiguration == null) - services.AddSingleton(_ => configurationBuilder.Build()); + { + var configurationManager = new ConfigurationManager(); + configurationBuilder.AddConfiguration(configurationBuilder.Build()); + services.AddSingleton(_ => configurationManager); + } return services; } diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/LocalMasaConfigurationRepository.cs b/src/Contrib/Configuration/Masa.Contrib.Configuration/LocalMasaConfigurationRepository.cs index 80478d62d..18d6b4e75 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/LocalMasaConfigurationRepository.cs +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/LocalMasaConfigurationRepository.cs @@ -25,35 +25,10 @@ public LocalMasaConfigurationRepository( private void Initialize(IConfiguration configuration) { - Dictionary data = new(); - GetData(configuration, configuration.GetChildren(), ref data); + var data = configuration.ConvertToDictionary(); _data = new Properties(data); } - private void GetData(IConfiguration configuration, IEnumerable configurationSections, - ref Dictionary dictionary) - { - foreach (var configurationSection in configurationSections) - { - var section = configuration.GetSection(configurationSection.Path); - - var childrenSections = section.GetChildren()?.ToList() ?? new List(); - - if (!section.Exists() || !childrenSections.Any()) - { - var key = section.Path; - if (!dictionary.ContainsKey(key)) - { - dictionary.Add(key, configuration[section.Path]); - } - } - else - { - GetData(configuration, childrenSections, ref dictionary); - } - } - } - public override Properties Load() { return _data; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs new file mode 100644 index 000000000..491878cd2 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs @@ -0,0 +1,26 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization.Dcc; + +public class DccLocalizationResourceContributor : ILocalizationResourceContributor +{ + private readonly IConfigurationSection _configurationSection; + + public string CultureName { get; } + + public DccLocalizationResourceContributor(string appId, string configObject, IMasaConfiguration masaConfiguration) + { + _configurationSection = masaConfiguration.ConfigurationApi.Get(appId).GetSection(configObject); + } + + public string? GetOrNull(string name) + { + if (_configurationSection.Exists()) + { + return _configurationSection.GetValue(name); + } + + return null; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj new file mode 100644 index 000000000..5cebed1e7 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs new file mode 100644 index 000000000..b38ee13b2 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Configuration; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.Localization; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/DefaultResource.cs similarity index 63% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/DefaultResource.cs index 9451a0721..edfed412e 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/DefaultResource.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.Localization.Tests; +namespace Masa.Contrib.Globalization.Localization; -public class LocalizationResource +public class DefaultResource { } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..9236ca0ea --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,24 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Microsoft.Extensions.DependencyInjection; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddMasaLocalization(this IServiceCollection services, Action? action = null) + { + MasaApp.TrySetServiceCollection(services); + services.TryAddSingleton(typeof(IMasaStringLocalizer<>), typeof(MasaStringLocalizer<>)); + services.AddSingleton(); + + if (action != null) + { + services.Configure(action); + } + + _ = services.BuildServiceProvider().GetRequiredService>(); + services.AddLocalization(); + return services; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs new file mode 100644 index 000000000..35ff8bab6 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs @@ -0,0 +1,89 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization; + +public abstract class FileLocalizationConfigurationProvider : ConfigurationProvider +{ + protected IConfigurationBuilder ConfigurationBuilder; + private readonly string _resourceType; + private readonly List _filePaths; + private readonly bool _useMasaConfiguration; + private readonly Dictionary> _dictionary; + private readonly IConfiguration _configuration; + + public FileLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) + { + ConfigurationBuilder = new ConfigurationBuilder(); + _resourceType = configurationSource.ResourceType.Name; + _filePaths = configurationSource.LocalizationFilePaths; + _useMasaConfiguration = configurationSource.UseMasaConfiguration; + _dictionary = new(); + + _filePaths.ForEach(filePath => + { + var file = new FileInfo(filePath); + AddFile(file.Directory!.FullName, file.Name); + }); + _configuration = ConfigurationBuilder.Build(); + ChangeToken.OnChange(() => _configuration.GetReloadToken(), Load); + } + + public override void Load() + { + _filePaths.ForEach(filePath => + { + var file = new FileInfo(filePath); + var configuration = InitializeConfiguration(file.Directory!.FullName, file.Name); + var culture = configuration.GetValue(Const.CULTURE); + LocalizationResourceConfiguration.Dictionary[filePath] = culture; + var dictionary = configuration.ConvertToDictionary(); + dictionary.Remove(Const.CULTURE); + _dictionary[FormatKey(culture)] = dictionary.ToDictionary( + keyValuePair => keyValuePair.Key.TrimStart($"{Const.TESTS}:"), + keyValuePair => keyValuePair.Value); + }); + + Data = FormatData(); + } + + private string FormatKey(string cultureName) + => _useMasaConfiguration ? + string.Join(ConfigurationPath.KeyDelimiter, new List() + { + SectionTypes.Local.ToString(), + Const.DEFAULT_LOCAL_SECTION, + _resourceType, + cultureName + }) + : string.Join(ConfigurationPath.KeyDelimiter, new List() + { + Const.DEFAULT_LOCAL_SECTION, + _resourceType, + cultureName + }); + + private IConfiguration InitializeConfiguration(string basePath, string fileName) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(basePath) + .AddJsonFile(fileName, false, true) + .Build(); + return configuration; + } + + private Dictionary FormatData() + { + var data = new Dictionary(); + foreach (var item in _dictionary) + { + foreach (var resource in item.Value) + { + data[$"{item.Key}{ConfigurationPath.KeyDelimiter}{resource.Key}"] = resource.Value; + } + } + return data; + } + + protected abstract void AddFile(string basePath, string fileName); +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs new file mode 100644 index 000000000..b89cf21e5 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs @@ -0,0 +1,14 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.Localization; + +public class Const +{ + public const string DEFAULT_LOCAL_SECTION = "Localization"; + + public const string CULTURE = "culture"; + + public const string TESTS = "texts"; +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs new file mode 100644 index 000000000..43959bef6 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization; + +internal static class LocalizationResourceConfiguration +{ + internal static Dictionary Dictionary { get; set; } = new(); +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs deleted file mode 100644 index 3198e0635..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonFileLocalizationResourceContributor.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization; - -public class JsonFileLocalizationResourceContributor : FileLocalizationResourceContributorBase -{ - private readonly JsonSerializerOptions _deserializeOptions; - - public JsonFileLocalizationResourceContributor( - Type resourceType, - string filePath, - JsonSerializerOptions deserializeOptions, - ILoggerFactory? loggerFactory) : base(resourceType, filePath, loggerFactory) - { - _deserializeOptions = deserializeOptions; - } - - protected override (string CultureName, Dictionary Dictionary) ParseCultureNameAndResourceFromFileContent( - string fileContent) - { - JsonLocalizationFile jsonFile; - try - { - jsonFile = JsonSerializer.Deserialize(fileContent, _deserializeOptions) ?? - throw new UserFriendlyException($"Can not parse json string. json file path: {fileContent}"); - } - catch (JsonException ex) - { - throw new UserFriendlyException("Can not parse json string. " + ex.Message); - } - var cultureCode = jsonFile.Culture; - if (string.IsNullOrEmpty(cultureCode)) - { - throw new UserFriendlyException("Culture is empty in language json file."); - } - - var dictionary = new Dictionary(); - var duplicateNames = new List(); - foreach (var item in jsonFile.Texts) - { - if (string.IsNullOrEmpty(item.Key)) - { - throw new UserFriendlyException("The key is empty in given json string."); - } - - if (dictionary.ContainsKey(item.Key)) - { - duplicateNames.Add(item.Key); - } - - dictionary[item.Key] = new LocalizedString(item.Key, - item.Value.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", Environment.NewLine)); - } - - if (duplicateNames.Count > 0) - { - throw new UserFriendlyException( - "A dictionary can not contain same key twice. There are some duplicated names: " + - string.Join(", ", duplicateNames)); - } - - return new(jsonFile.Culture, dictionary); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs new file mode 100644 index 000000000..44e20c014 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.Localization; + +public class JsonLocalizationConfigurationProvider : FileLocalizationConfigurationProvider +{ + public JsonLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) : base(configurationSource) + { + + } + + protected override void AddFile(string basePath, string fileName) + { + ConfigurationBuilder = ConfigurationBuilder + .SetBasePath(basePath) + .AddJsonFile(fileName, false, true); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs new file mode 100644 index 000000000..0f3542ff1 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs @@ -0,0 +1,26 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.Localization; + +public class JsonLocalizationConfigurationSource : IConfigurationSource +{ + public Type ResourceType { get; } + + public readonly List LocalizationFilePaths; + + public bool UseMasaConfiguration { get; } + + public JsonLocalizationConfigurationSource(Type resourceType, List localizationFilePaths, bool useMasaConfiguration) + { + ResourceType = resourceType; + LocalizationFilePaths = localizationFilePaths; + UseMasaConfiguration = useMasaConfiguration; + } + + public IConfigurationProvider Build(IConfigurationBuilder builder) + { + return new JsonLocalizationConfigurationProvider(this); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs deleted file mode 100644 index 4a75ba7cc..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationFile.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization; - -public class JsonLocalizationFile -{ - /// - /// Culture name - /// eg: en,en-us, zh-CN - /// - public string Culture { get; set; } - - public Dictionary Texts { get; set; } - - public JsonLocalizationFile() - { - Texts = new Dictionary(); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs new file mode 100644 index 000000000..b1fc601cb --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs @@ -0,0 +1,34 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.Localization; + +public class LocalLocalizationResourceContributor : ILocalizationResourceContributor +{ + private readonly IConfiguration _configuration; + + public Type ResourceType { get; } + + public string CultureName { get; } + + public LocalLocalizationResourceContributor( + Type resourceType, + string cultureName, + IConfiguration configuration, + IMasaConfiguration? masaConfiguration = null) + { + ResourceType = resourceType; + CultureName = cultureName; + _configuration = masaConfiguration?.Local ?? configuration; + } + + public string? GetOrNull(string name) + { + var section = _configuration.GetSection(Const.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); + if (section != null && section.Exists()) + { + return section.GetValue(name); + } + return null; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs index c66c75982..b7a88b532 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs @@ -6,25 +6,26 @@ namespace Masa.Contrib.Globalization.Localization; public static class LocalizationResourceExtensions { private static readonly string _baseDirectory = AppDomain.CurrentDomain.BaseDirectory; - private static ILoggerFactory? _loggerFactory; + private static IConfiguration? _configuration; + private static IMasaConfiguration? _masaConfiguration; public static LocalizationResource AddJson( this LocalizationResource localizationResource, - string languageDirectory, - JsonSerializerOptions deserializeOptions) + string languageDirectory) { languageDirectory.CheckIsNullOrWhiteSpace(); if (!Directory.Exists(languageDirectory)) { - var path = Path.Combine(_baseDirectory, languageDirectory); + var path = Path.Combine(_baseDirectory, languageDirectory.TrimStart("/")); if (!Directory.Exists(path)) { throw new UserFriendlyException($"[{languageDirectory}] does not exist"); } + languageDirectory = path; } - var resources = GetResources(localizationResource, languageDirectory, deserializeOptions); + var resources = GetResources(localizationResource, languageDirectory); foreach (var resource in resources) { localizationResource.AddContributor(resource); @@ -35,21 +36,52 @@ public static LocalizationResource AddJson( public static List GetResources( LocalizationResource localizationResource, - string languageDirectory, - JsonSerializerOptions deserializeOptions) + string languageDirectory) { - var files = Directory.GetFiles(languageDirectory).ToList(); + var filePaths = Directory.GetFiles(languageDirectory).ToList(); - _loggerFactory ??= MasaApp.GetServices().BuildServiceProvider().GetService(); + _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); + _masaConfiguration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); - return files.Select - (file => (ILocalizationResourceContributor)new JsonFileLocalizationResourceContributor + var services = MasaApp.GetServices(); + services.AddJsonLocalizationConfigurationSource(ref _configuration, _masaConfiguration, localizationResource.ResourceType, filePaths); + + return filePaths.Select + (filePath => (ILocalizationResourceContributor)new LocalLocalizationResourceContributor ( localizationResource.ResourceType, - file, - deserializeOptions, _loggerFactory + LocalizationResourceConfiguration.Dictionary[filePath], + _configuration!, + _masaConfiguration ) ) .ToList(); } + + private static void AddJsonLocalizationConfigurationSource( + this IServiceCollection services, + ref IConfiguration? configuration, + IMasaConfiguration? masaConfiguration, + Type resourceType, + List filePaths) + { + ConfigurationManager configurationManager = new(); + if (configuration == null) + { + configuration = configurationManager; + services.AddSingleton(configurationManager); + } + else if (configuration is not ConfigurationManager) + { + configurationManager.AddConfiguration(configuration); + } + else if (configuration is ConfigurationManager configurationManagerTemp) + { + configurationManager = configurationManagerTemp; + } + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.Add(new JsonLocalizationConfigurationSource(resourceType, filePaths, masaConfiguration != null)); + var localizationConfiguration = configurationBuilder.Build(); + configurationManager.AddConfiguration(localizationConfiguration); + } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj index 93e9575a4..5f23e329a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs new file mode 100644 index 000000000..a15067f0d --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs @@ -0,0 +1,54 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization; + +public class MasaStringLocalizer : IMasaStringLocalizer +{ + private readonly LocalizationResource? _localizationResource; + private readonly IStringLocalizer? _stringLocalizer; + private readonly string _defaultCultureName; + public virtual string this[string name] => GetLocalizedString(name); + + public virtual string this[string name, params object[] arguments] + { + get + { + ArgumentNullException.ThrowIfNull(name); + + var value = this[name]; + return string.Format(value, arguments); + } + } + + public MasaStringLocalizer(IStringLocalizerFactory? stringLocalizerFactory, IOptions options) + { + _stringLocalizer = stringLocalizerFactory?.Create(typeof(TResourceSource)); + _localizationResource = options.Value.Resources.GetOrNull(); + _defaultCultureName = options.Value.DefaultCultureName; + } + + private string GetLocalizedString(string name) + { + var resourceContributor = _localizationResource?.GetResourceContributor(); + if (resourceContributor != null) + { + return resourceContributor.GetOrNull(name) ?? GetLocalizedStringByDefaultCultureName(name); + } + if (_stringLocalizer != null) + { + return _stringLocalizer.GetString(name); + } + throw new NotImplementedException(); + } + + private string GetLocalizedStringByDefaultCultureName(string name) + { + var resourceContributor = _localizationResource!.GetResourceContributor(new CultureInfo(_defaultCultureName)); + if (resourceContributor != null) + { + return resourceContributor.GetOrNull(name) ?? name; + } + throw new NotImplementedException(); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs index a902f868c..0272ab441 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs @@ -1,9 +1,13 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Microsoft.Extensions.Localization; -global using Microsoft.Extensions.Logging; -global using System.Reflection; -global using System.Text.Json; +global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; +global using Masa.Contrib.Globalization.Localization; +global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.DependencyInjection.Extensions; +global using Microsoft.Extensions.Localization; +global using Microsoft.Extensions.Options; +global using Microsoft.Extensions.Primitives; +global using System.Globalization; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs new file mode 100644 index 000000000..31c9c8b1d --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs @@ -0,0 +1,82 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization.Tests; + +[TestClass] +public class LocalizationResourceTest +{ + [DataTestMethod] + [DataRow("zh-cn","吉姆")] + [DataRow("en","Jim")] + public void TestLocalization(string cultureName, string expectedValue) + { + var services = new ServiceCollection(); + services.Configure(masaLocalizationOptions => + { + masaLocalizationOptions.DefaultCultureName = "en"; + + masaLocalizationOptions.Resources + .Add() + .AddJson("/Resources"); + }); + services.AddLogging(); + services.AddMasaLocalization(); + var serviceProvider = services.BuildServiceProvider(); + CultureInfo.CurrentUICulture = new CultureInfo(cultureName); + var masaStringLocalizer = serviceProvider.GetRequiredService>(); + var value = masaStringLocalizer["Name"]; + Assert.AreEqual(expectedValue, value); + value = masaStringLocalizer["Name2"]; + Assert.AreEqual("Name2", value); + } + + [DataTestMethod] + [DataRow("zh-cn","吉姆")] + [DataRow("en","Jim")] + public void TestLocalization2(string cultureName, string expectedValue) + { + var builder = WebApplication.CreateBuilder(); + builder.Services.Configure(masaLocalizationOptions => + { + masaLocalizationOptions.DefaultCultureName = "en"; + + masaLocalizationOptions.Resources + .Add() + .AddJson("/Resources"); + }); + builder.Services.AddMasaLocalization(); + var serviceProvider = builder.Services.BuildServiceProvider(); + CultureInfo.CurrentUICulture = new CultureInfo(cultureName); + var masaStringLocalizer = serviceProvider.GetRequiredService>(); + var value = masaStringLocalizer["Name"]; + Assert.AreEqual(expectedValue, value); + value = masaStringLocalizer["Name2"]; + Assert.AreEqual("Name2", value); + } + + [DataTestMethod] + [DataRow("zh-cn","吉姆")] + [DataRow("en","Jim")] + public void TestLocalizationByMasaConfigurationLocal(string cultureName, string expectedValue) + { + var builder = WebApplication.CreateBuilder(); + builder.Services.AddMasaConfiguration(); + builder.Services.Configure(masaLocalizationOptions => + { + masaLocalizationOptions.DefaultCultureName = "en"; + + masaLocalizationOptions.Resources + .Add() + .AddJson("/Resources"); + }); + builder.Services.AddMasaLocalization(); + var serviceProvider = builder.Services.BuildServiceProvider(); + CultureInfo.CurrentUICulture = new CultureInfo(cultureName); + var masaStringLocalizer = serviceProvider.GetRequiredService>(); + var value = masaStringLocalizer["Name"]; + Assert.AreEqual(expectedValue, value); + value = masaStringLocalizer["Name2"]; + Assert.AreEqual("Name2", value); + } +} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj index 2f70b9e94..2598eb62d 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj @@ -23,11 +23,19 @@ + - + + + PreserveNewest + + + + PreserveNewest + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json new file mode 100644 index 000000000..8a9921be6 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json @@ -0,0 +1,6 @@ +{ + "culture": "en", + "texts": { + "Name": "Jim" + } +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json new file mode 100644 index 000000000..50ae69e4f --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json @@ -0,0 +1,6 @@ +{ + "culture": "zh-Cn", + "texts": { + "Name": "吉姆" + } +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs new file mode 100644 index 000000000..aee10b23f --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs @@ -0,0 +1,8 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Microsoft.AspNetCore.Builder; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Localization; +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using System.Globalization; From f05376a418805d31631f0db18522c8e6dc4629fd Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Tue, 18 Oct 2022 20:12:38 +0800 Subject: [PATCH 05/38] feat: Add Localization --- Masa.Framework.sln | 11 -- Masa.Framework.sln.DotSettings | 1 + .../{LanguageInfo.cs => Const.cs} | 8 +- .../ILocalizationResourceContributor.cs | 1 + .../IMasaStringLocalizer.cs | 6 + .../IMasaStringLocalizerFactory.cs | 1 + .../IMasaStringLocalizerOfT.cs | 1 + .../LocalizationResource.cs | 14 +- .../LocalizationResourceConfiguration.cs | 11 ++ .../LocalizationResourceDictionary.cs | 15 ++- ...ngBlocks.Globalization.Localization.csproj | 5 +- .../MasaStringLocalizerFactory.cs | 1 + .../Options/MasaLocalizationOptions.cs | 15 +-- ...BuildingBlocks.Globalization.Timing.csproj | 9 -- .../ConfigurationApiExtensions.cs | 6 +- .../DccConfig.cs | 11 ++ .../DistributedCacheClientExtensions.cs | 2 +- .../Internal/Model/StaticConfig.cs | 11 -- .../MasaConfigurationExtensions.cs | 7 +- ...onfigurationApiMasaConfigurationOptions.cs | 2 +- .../Options/DccSectionOptions.cs | 2 + .../DccLocalizationResourceContributor.cs | 11 +- .../LocalizationOptionsExtensions.cs | 35 +++++ .../LocalizationResourceExtensions.cs | 24 ++++ ...trib.Globalization.Localization.Dcc.csproj | 1 + .../_Imports.cs | 4 + .../LocalizationOptionsExtensions.cs | 20 +++ .../LocalizationResourceExtensions.cs | 127 ++++++++++++++++++ .../Extensions/ServiceCollectionExtensions.cs | 33 ++++- .../FileLocalizationConfigurationProvider.cs | 75 +++++------ .../Internal/Const.cs | 11 +- .../LocalizationResourceConfiguration.cs | 9 -- .../JsonLocalizationConfigurationProvider.cs | 9 +- .../JsonLocalizationConfigurationSource.cs | 18 ++- .../LocalLocalizationResourceContributor.cs | 8 +- .../LocalizationOptions.cs} | 6 + .../LocalizationResourceExtensions.cs | 87 ------------ ....Contrib.Globalization.Localization.csproj | 22 +-- .../MasaStringLocalizerOfT.cs | 29 ++-- .../_Imports.cs | 1 + .../LocalizationResourceTest.cs | 65 ++++----- ...ib.Globalization.Localization.Tests.csproj | 17 ++- .../Resources/en-US.json | 6 + .../Resources/en.json | 6 - .../Resources/supportedCultures.json | 4 + .../Resources/zh-CN.json | 6 + .../Resources/zh-Cn.json | 6 - .../_Imports.cs | 1 + 48 files changed, 459 insertions(+), 322 deletions(-) rename src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/{LanguageInfo.cs => Const.cs} (50%) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj create mode 100644 src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/DccConfig.cs delete mode 100644 src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Model/StaticConfig.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs rename src/{BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs => Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationOptions.cs} (62%) delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en-US.json delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-CN.json delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 0f9615638..ef0a1d066 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -579,8 +579,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globali EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.Timing", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.Timing\Masa.BuildingBlocks.Globalization.Timing.csproj", "{548318DB-8655-421C-901A-B1A6BDC05962}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests", "src\Contrib\Service\Caller\Authentication\Tests\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests.csproj", "{BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization", "src\Contrib\Globalization\Masa.Contrib.Globalization.Localization\Masa.Contrib.Globalization.Localization.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" @@ -2047,14 +2045,6 @@ Global {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.Build.0 = Release|Any CPU {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.ActiveCfg = Release|Any CPU {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.Build.0 = Release|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|Any CPU.Build.0 = Debug|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|x64.ActiveCfg = Debug|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Debug|x64.Build.0 = Debug|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Release|Any CPU.ActiveCfg = Release|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Release|Any CPU.Build.0 = Release|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Release|x64.ActiveCfg = Release|Any CPU - {548318DB-8655-421C-901A-B1A6BDC05962}.Release|x64.Build.0 = Release|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Debug|Any CPU.Build.0 = Debug|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2377,7 +2367,6 @@ Global {D10FC534-0091-42B4-809F-82C1E2164ED5} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} {AC84401A-58FD-4786-9E10-BA99D17ABB3E} = {D10FC534-0091-42B4-809F-82C1E2164ED5} - {548318DB-8655-421C-901A-B1A6BDC05962} = {D10FC534-0091-42B4-809F-82C1E2164ED5} {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} = {68491FED-7441-4B58-989D-DF6F198FC91A} {9BB5CC86-C2E8-4859-9610-50DB263605A3} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} {8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} diff --git a/Masa.Framework.sln.DotSettings b/Masa.Framework.sln.DotSettings index 85260b77e..5b0923e57 100644 --- a/Masa.Framework.sln.DotSettings +++ b/Masa.Framework.sln.DotSettings @@ -1,4 +1,5 @@  True + True True True \ No newline at end of file diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Const.cs similarity index 50% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Const.cs index 1b94e62ce..a16c8122d 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Const.cs @@ -1,11 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Microsoft.Extensions.Localization; +namespace Masa.BuildingBlocks.Globalization.Localization; -public class LanguageInfo +public static class Const { - string CultureName { get; } - - string DisplayName { get; } + public const string DEFAULT_LOCAL_SECTION = "Localization"; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs index ed0757cd9..571d88e31 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; public interface ILocalizationResourceContributor diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs index ad03813da..b2b063022 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.Extensions.Localization; public interface IMasaStringLocalizer @@ -17,4 +19,8 @@ public interface IMasaStringLocalizer /// The values to format the string with. /// The formatted string resource as a . string this[string name, params object[] arguments] { get; } + + string T(string name); + + string T(string name, params object[] arguments); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs index 3a48d3a95..02aa5b95c 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; public interface IMasaStringLocalizerFactory diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs index 32612e177..93b116cd4 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; public interface IMasaStringLocalizer : IMasaStringLocalizer diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs index a8c75b531..d9469bd71 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs @@ -1,27 +1,25 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; public class LocalizationResource { - private Dictionary _dictionary { get; } + private readonly Dictionary _dictionary; public Type ResourceType { get; } - public string? DefaultCultureName { get; internal set; } - - public LocalizationResource(Type resourceType, string? defaultCultureName) + public LocalizationResource(Type resourceType) { _dictionary = new(StringComparer.OrdinalIgnoreCase); ResourceType = resourceType; - DefaultCultureName = defaultCultureName; } - public void AddContributor(ILocalizationResourceContributor localizationResourceContributor) + public void AddContributor(string cultureName,ILocalizationResourceContributor localizationResourceContributor) { - if (_dictionary.Any(d => d.Key.Equals(localizationResourceContributor.CultureName, StringComparison.OrdinalIgnoreCase))) - throw new Exception($"The {localizationResourceContributor.CultureName} already exists with {ResourceType.FullName}"); + if (_dictionary.ContainsKey(cultureName)) + throw new ArgumentException($"The {cultureName} already exists with {ResourceType.FullName}"); _dictionary.Add(localizationResourceContributor.CultureName, localizationResourceContributor); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs new file mode 100644 index 000000000..07d81fe1e --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.Localization; + +public static class LocalizationResourceConfiguration +{ + public static readonly string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; + + public static string DefaultCultureName { get; set; } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs index 9967a7ecf..8c2096992 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs @@ -1,21 +1,23 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; +[Serializable] public class LocalizationResourceDictionary : Dictionary { - public LocalizationResource Add(string? defaultCultureName = null) + public LocalizationResource Add() { - return Add(typeof(TResource), defaultCultureName); + return Add(typeof(TResource)); } - public LocalizationResource Add(Type resourceType, string? defaultCultureName = null) + public LocalizationResource Add(Type resourceType) { if (ContainsKey(resourceType)) - throw new Exception("This resource is already added before: " + resourceType.FullName); + throw new ArgumentException("This resource is already added before: " + resourceType.FullName); - return this[resourceType] = new LocalizationResource(resourceType, defaultCultureName); + return this[resourceType] = new LocalizationResource(resourceType); } public LocalizationResource? GetOrNull(Type resourceType) @@ -26,6 +28,5 @@ public LocalizationResource Add(Type resourceType, string? defaultCultureName = return this[resourceType]; } - public LocalizationResource? GetOrNull() - => GetOrNull(typeof(TResource)); + public LocalizationResource? GetOrNull() => GetOrNull(typeof(TResource)); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj index 64d9650fb..f9507c745 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj @@ -4,12 +4,9 @@ net6.0 enable enable + Masa.BuildingBlocks.Globalization.Localization - - - - diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs index 1dbad59af..69cc02e60 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; public class MasaStringLocalizerFactory : IMasaStringLocalizerFactory diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs index eeea604a2..407d6e6a4 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs @@ -1,15 +1,12 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; public class MasaLocalizationOptions { - public string DefaultCultureName { get; set; } - - public Type DefaultResourceType { get; set; } - - public List Languages { get; set; } + public Type? DefaultResourceType { get; set; } public LocalizationResourceDictionary Resources { get; } @@ -17,12 +14,4 @@ public MasaLocalizationOptions() { Resources = new (); } - - public void FormatResources() - { - foreach (var resource in Resources) - { - resource.Value.DefaultCultureName ??= DefaultCultureName; - } - } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj deleted file mode 100644 index eb2460e91..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/Masa.BuildingBlocks.Globalization.Timing.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net6.0 - enable - enable - - - diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/ConfigurationApiExtensions.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/ConfigurationApiExtensions.cs index 602d1f3fa..cd6916244 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/ConfigurationApiExtensions.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/ConfigurationApiExtensions.cs @@ -1,17 +1,17 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Configuration; +namespace Masa.Contrib.Configuration.ConfigurationApi.Dcc; public static class ConfigurationApiExtensions { public static IConfiguration GetDefault(this IConfigurationApi configurationApi) { - return configurationApi.Get(StaticConfig.AppId); + return configurationApi.Get(DccConfig.AppId); } public static IConfiguration GetPublic(this IConfigurationApi configurationApi) { - return configurationApi.Get(StaticConfig.PublicId); + return configurationApi.Get(DccConfig.PublicId); } } diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/DccConfig.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/DccConfig.cs new file mode 100644 index 000000000..8334e4b5b --- /dev/null +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/DccConfig.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Configuration.ConfigurationApi.Dcc; + +public static class DccConfig +{ + public static string AppId { get; internal set; } + + public static string PublicId { get; internal set; } +} diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Extensions/DistributedCacheClientExtensions.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Extensions/DistributedCacheClientExtensions.cs index 82dd2c0aa..2c9c02bf1 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Extensions/DistributedCacheClientExtensions.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Extensions/DistributedCacheClientExtensions.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Caching; +namespace Masa.Contrib.Configuration.ConfigurationApi.Dcc.Internal.Extensions; internal static class DistributedCacheClientExtensions { diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Model/StaticConfig.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Model/StaticConfig.cs deleted file mode 100644 index a4ec62030..000000000 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Internal/Model/StaticConfig.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Configuration.ConfigurationApi.Dcc.Internal.Model; - -internal static class StaticConfig -{ - public static string AppId { get; set; } - - public static string PublicId { get; set; } -} diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs index 49bf41f49..0c181281f 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs @@ -2,6 +2,9 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + +using Masa.Contrib.Configuration.ConfigurationApi.Dcc; + namespace Masa.BuildingBlocks.Configuration; public static class MasaConfigurationExtensions @@ -148,8 +151,8 @@ public static DccConfigurationOptions ComplementAndCheckDccConfigurationOption( dccConfigurationOptions.ExpandSections.Add(publicSection); } - StaticConfig.AppId = dccConfigurationOptions.DefaultSection.AppId; - StaticConfig.PublicId = dccConfigurationOptions.PublicId; + DccConfig.AppId = dccConfigurationOptions.DefaultSection.AppId; + DccConfig.PublicId = dccConfigurationOptions.PublicId; if (dccConfigurationOptions.ExpandSections.Any(sectionOption => sectionOption.AppId == dccConfigurationOptions.DefaultSection.AppId)) diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/ConfigurationApiMasaConfigurationOptions.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/ConfigurationApiMasaConfigurationOptions.cs index 46f68e0ae..cc6203431 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/ConfigurationApiMasaConfigurationOptions.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/ConfigurationApiMasaConfigurationOptions.cs @@ -11,7 +11,7 @@ public abstract class ConfigurationApiMasaConfigurationOptions : MasaConfigurati [JsonIgnore] public sealed override string? ParentSection => AppId; - public virtual string AppId => StaticConfig.AppId; + public virtual string AppId => DccConfig.AppId; /// /// The section null means same as the class name, else load from the specify section diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/DccSectionOptions.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/DccSectionOptions.cs index da216b5b0..58f2afe54 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/DccSectionOptions.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/Options/DccSectionOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +using Masa.Contrib.Configuration.ConfigurationApi.Dcc.Internal.Extensions; + namespace Masa.Contrib.Configuration.ConfigurationApi.Dcc.Options; public class DccSectionOptions diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs index 491878cd2..8226c05a2 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs @@ -9,9 +9,15 @@ public class DccLocalizationResourceContributor : ILocalizationResourceContribut public string CultureName { get; } - public DccLocalizationResourceContributor(string appId, string configObject, IMasaConfiguration masaConfiguration) + public DccLocalizationResourceContributor( + string appId, + string configObject, + string cultureName, + IMasaConfiguration masaConfiguration) { - _configurationSection = masaConfiguration.ConfigurationApi.Get(appId).GetSection(configObject); + CultureName = cultureName; + + _configurationSection = masaConfiguration.ConfigurationApi.Get(appId).GetSection($"{configObject}.{cultureName}"); } public string? GetOrNull(string name) @@ -20,7 +26,6 @@ public DccLocalizationResourceContributor(string appId, string configObject, IMa { return _configurationSection.GetValue(name); } - return null; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs new file mode 100644 index 000000000..2724be1d2 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs @@ -0,0 +1,35 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.Localization; + +public static class LocalizationOptionsExtensions +{ + public static LocalizationOptions UseDcc( + this LocalizationOptions localization, + params string[] cultureNames) + => localization.UseDcc(DccConfig.AppId, "I18n", cultureNames); + + public static LocalizationOptions UseDcc( + this LocalizationOptions localization, + string configObject, + params string[] cultureNames) + => localization.UseDcc(DccConfig.AppId, configObject, cultureNames); + + public static LocalizationOptions UseDcc( + this LocalizationOptions localization, + string appId, + string configObject, + params string[] cultureNames) + { + var services = MasaApp.GetServices(); + services.Configure(options => + { + options.Resources + .Add() + .UseDcc(appId, configObject, cultureNames); + }); + return localization; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs new file mode 100644 index 000000000..abc39203f --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs @@ -0,0 +1,24 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.Localization; + +public static class LocalizationResourceExtensions +{ + public static LocalizationResource UseDcc( + this LocalizationResource localizationResource, + string appId, + string configObject, + params string[] cultureNames) + { + var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); + var masaConfiguration = serviceProvider.GetRequiredService(); + foreach (var cultureName in cultureNames) + { + var resourceContributor = new DccLocalizationResourceContributor(appId, configObject, cultureName, masaConfiguration); + localizationResource.AddContributor(cultureName, resourceContributor); + } + return localizationResource; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj index 5cebed1e7..8e57ba66d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj @@ -9,6 +9,7 @@ + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs index b38ee13b2..f33e0a245 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs @@ -2,5 +2,9 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Data; +global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; +global using Masa.Contrib.Globalization.Localization.Dcc; global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Localization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs new file mode 100644 index 000000000..039f0122e --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization.Extensions; + +public static class MasaLocalizationOptionsExtensions +{ + public static void UseJson(this LocalizationOptions _, + string languageDirectory, + params string[] cultureNames) + { + var services = MasaApp.GetServices(); + services.Configure(options => + { + options.Resources + .Add() + .AddJson(languageDirectory, cultureNames); + }); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs new file mode 100644 index 000000000..1b17d7535 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs @@ -0,0 +1,127 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.Localization; + +public static class LocalizationResourceExtensions +{ + private static IConfiguration? _configuration; + + private static IMasaConfiguration? _masaConfiguration; + + public static LocalizationResource AddJson( + this LocalizationResource localizationResource, + string languageDirectory, + params string[] cultureNames) + { + languageDirectory = GetAndCheckLanguageDirectory(languageDirectory); + if (cultureNames.Length == 0) + { + cultureNames = GetCultureNames(languageDirectory).ToArray(); + } + var resourceContributors = GetResourceContributors( + localizationResource, + languageDirectory, + cultureNames); + foreach (var resourceContributor in resourceContributors) + { + localizationResource.AddContributor(resourceContributor.CultureName, resourceContributor); + } + + return localizationResource; + } + + private static string GetAndCheckLanguageDirectory(string languageDirectory) + { + languageDirectory.CheckIsNullOrWhiteSpace(); + + if (!Directory.Exists(languageDirectory)) + { + var path = Path.Combine(LocalizationResourceConfiguration.BaseDirectory, languageDirectory.TrimStart("/")); + if (!Directory.Exists(path)) + { + throw new UserFriendlyException($"[{languageDirectory}] does not exist"); + } + languageDirectory = path; + } + else + { + languageDirectory = Path.GetFullPath(languageDirectory); + } + return languageDirectory; + } + + private static List GetCultureNames(string languageDirectory) + { + var supportCultureFilePath = Path.Combine(languageDirectory, Internal.Const.SUPPORTED_CULTURES_FILE_NAME); + var content = File.ReadAllText(supportCultureFilePath); + return System.Text.Json.JsonSerializer.Deserialize>(content) ?? new List() + { + "en-US" + }; + } + + private static List GetResourceContributors( + LocalizationResource localizationResource, + string languageDirectory, + IEnumerable cultureNames) + { + _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); + _masaConfiguration ??= + MasaApp.GetServices().BuildServiceProvider().GetService(); + + var services = MasaApp.GetServices(); + + var configuration = _configuration; + + var useMasaConfiguration = _masaConfiguration != null; + services.AddJsonLocalizationConfigurationSource( + languageDirectory, + cultureNames, + localizationResource.ResourceType, + ref configuration, + useMasaConfiguration); + _configuration = configuration; + + return cultureNames.Select + (cultureName => (ILocalizationResourceContributor)new LocalLocalizationResourceContributor + ( + localizationResource.ResourceType, + cultureName, + useMasaConfiguration ? _configuration!.GetSection(SectionTypes.Local.ToString()) : _configuration! + ) + ) + .ToList(); + } + + private static void AddJsonLocalizationConfigurationSource( + this IServiceCollection services, + string languageDirectory, + IEnumerable cultureNames, + Type resourceType, + ref IConfiguration? configuration, + bool useMasaConfiguration) + { + ConfigurationManager configurationManager = new(); + if (configuration == null) + { + configuration = configurationManager; + services.AddSingleton(configurationManager); + } + else if (configuration is not ConfigurationManager) + { + configurationManager.AddConfiguration(configuration); + } + else if (configuration is ConfigurationManager configurationManagerTemp) + { + configurationManager = configurationManagerTemp; + } + var configurationBuilder = new ConfigurationBuilder(); + var jsonLocalizationConfigurationSource = + new JsonLocalizationConfigurationSource(resourceType, languageDirectory, cultureNames, useMasaConfiguration); + configurationBuilder.Add(jsonLocalizationConfigurationSource); + var localizationConfiguration = configurationBuilder.Build(); + configurationManager.AddConfiguration(localizationConfiguration); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs index 9236ca0ea..9c9100aa6 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs @@ -2,23 +2,42 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { - public static IServiceCollection AddMasaLocalization(this IServiceCollection services, Action? action = null) + public static IServiceCollection AddMasaLocalization( + this IServiceCollection services, + Action? action) { MasaApp.TrySetServiceCollection(services); + return services.AddMasaLocalizationCore(action); + } + + public static IServiceCollection TestAddMasaLocalization( + this IServiceCollection services, + Action? action) + { + MasaApp.SetServiceCollection(services); + return services.AddMasaLocalizationCore(action); + } + + private static IServiceCollection AddMasaLocalizationCore(this IServiceCollection services, + Action? action) + { + services.Configure(options => + { + options.DefaultResourceType ??= typeof(DefaultResource); + }); services.TryAddSingleton(typeof(IMasaStringLocalizer<>), typeof(MasaStringLocalizer<>)); services.AddSingleton(); - if (action != null) - { - services.Configure(action); - } + action?.Invoke(new Masa.Contrib.Globalization.Localization.LocalizationOptions()); - _ = services.BuildServiceProvider().GetRequiredService>(); - services.AddLocalization(); + var masaLocalizationOptions = services.BuildServiceProvider().GetRequiredService>().Value; + var defaultResourceLocalizer = typeof(IMasaStringLocalizer<>).MakeGenericType(masaLocalizationOptions.DefaultResourceType!); + services.TryAddSingleton(serviceProvider => (IMasaStringLocalizer)serviceProvider.GetRequiredService(defaultResourceLocalizer)); return services; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs index 35ff8bab6..8b3374612 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs @@ -5,73 +5,59 @@ namespace Masa.Contrib.Globalization.Localization; public abstract class FileLocalizationConfigurationProvider : ConfigurationProvider { - protected IConfigurationBuilder ConfigurationBuilder; private readonly string _resourceType; - private readonly List _filePaths; + private readonly string _languageDirectory; + private readonly IEnumerable _cultureNames; private readonly bool _useMasaConfiguration; private readonly Dictionary> _dictionary; - private readonly IConfiguration _configuration; - public FileLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) + protected FileLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) { - ConfigurationBuilder = new ConfigurationBuilder(); _resourceType = configurationSource.ResourceType.Name; - _filePaths = configurationSource.LocalizationFilePaths; + _languageDirectory = configurationSource.LanguageDirectory; + _cultureNames = configurationSource.CultureNames; _useMasaConfiguration = configurationSource.UseMasaConfiguration; _dictionary = new(); - - _filePaths.ForEach(filePath => - { - var file = new FileInfo(filePath); - AddFile(file.Directory!.FullName, file.Name); - }); - _configuration = ConfigurationBuilder.Build(); - ChangeToken.OnChange(() => _configuration.GetReloadToken(), Load); } public override void Load() { - _filePaths.ForEach(filePath => + foreach (var cultureName in _cultureNames) { - var file = new FileInfo(filePath); - var configuration = InitializeConfiguration(file.Directory!.FullName, file.Name); - var culture = configuration.GetValue(Const.CULTURE); - LocalizationResourceConfiguration.Dictionary[filePath] = culture; - var dictionary = configuration.ConvertToDictionary(); - dictionary.Remove(Const.CULTURE); - _dictionary[FormatKey(culture)] = dictionary.ToDictionary( - keyValuePair => keyValuePair.Key.TrimStart($"{Const.TESTS}:"), - keyValuePair => keyValuePair.Value); - }); + var configuration = InitializeConfiguration(_languageDirectory, cultureName); + if (configuration.GetSection("$DefaultCulture").Exists() && configuration.GetValue("$DefaultCulture")) + { + LocalizationResourceConfiguration.DefaultCultureName = cultureName; + } + + _dictionary[FormatKey(cultureName)] = configuration.ConvertToDictionary(); + } Data = FormatData(); } private string FormatKey(string cultureName) - => _useMasaConfiguration ? - string.Join(ConfigurationPath.KeyDelimiter, new List() + { + var list = _useMasaConfiguration ? + new List() { SectionTypes.Local.ToString(), Const.DEFAULT_LOCAL_SECTION, _resourceType, cultureName - }) - : string.Join(ConfigurationPath.KeyDelimiter, new List() + } : + new List() { Const.DEFAULT_LOCAL_SECTION, _resourceType, cultureName - }); - - private IConfiguration InitializeConfiguration(string basePath, string fileName) - { - var configuration = new ConfigurationBuilder() - .SetBasePath(basePath) - .AddJsonFile(fileName, false, true) - .Build(); - return configuration; + }; + return string.Join(ConfigurationPath.KeyDelimiter, list); } + private IConfiguration InitializeConfiguration(string basePath, string cultureName) + => AddFile(new ConfigurationBuilder(), basePath, cultureName).Build(); + private Dictionary FormatData() { var data = new Dictionary(); @@ -85,5 +71,16 @@ private Dictionary FormatData() return data; } - protected abstract void AddFile(string basePath, string fileName); + protected abstract IConfigurationBuilder AddFile(IConfigurationBuilder configurationBuilder, string basePath, string cultureName); + + public void Initialize() + { + IConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); + foreach (var cultureName in _cultureNames) + { + configurationBuilder = AddFile(configurationBuilder, _languageDirectory, cultureName); + } + var configuration = configurationBuilder.Build(); + ChangeToken.OnChange(() => configuration.GetReloadToken(), Load); + } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs index b89cf21e5..6ddac5c97 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs @@ -1,14 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.Localization; +namespace Masa.Contrib.Globalization.Localization.Internal; -public class Const +internal static class Const { - public const string DEFAULT_LOCAL_SECTION = "Localization"; - - public const string CULTURE = "culture"; - - public const string TESTS = "texts"; + internal const string SUPPORTED_CULTURES_FILE_NAME = "supportedCultures.json"; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs deleted file mode 100644 index 43959bef6..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/LocalizationResourceConfiguration.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization; - -internal static class LocalizationResourceConfiguration -{ - internal static Dictionary Dictionary { get; set; } = new(); -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs index 44e20c014..35b651b46 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs @@ -6,15 +6,16 @@ namespace Masa.Contrib.Globalization.Localization; public class JsonLocalizationConfigurationProvider : FileLocalizationConfigurationProvider { - public JsonLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) : base(configurationSource) + public JsonLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) + : base(configurationSource) { } - protected override void AddFile(string basePath, string fileName) + protected override IConfigurationBuilder AddFile(IConfigurationBuilder configurationBuilder, string basePath, string cultureName) { - ConfigurationBuilder = ConfigurationBuilder + return configurationBuilder .SetBasePath(basePath) - .AddJsonFile(fileName, false, true); + .AddJsonFile(cultureName + ".json", false, true); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs index 0f3542ff1..eb22eb37b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs @@ -2,25 +2,35 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + namespace Masa.Contrib.Globalization.Localization; public class JsonLocalizationConfigurationSource : IConfigurationSource { public Type ResourceType { get; } - public readonly List LocalizationFilePaths; + public string LanguageDirectory { get; } + + public IEnumerable CultureNames { get; } public bool UseMasaConfiguration { get; } - public JsonLocalizationConfigurationSource(Type resourceType, List localizationFilePaths, bool useMasaConfiguration) + public JsonLocalizationConfigurationSource( + Type resourceType, + string languageDirectory, + IEnumerable cultureNames, + bool useMasaConfiguration) { ResourceType = resourceType; - LocalizationFilePaths = localizationFilePaths; + LanguageDirectory = languageDirectory; + CultureNames = cultureNames; UseMasaConfiguration = useMasaConfiguration; } public IConfigurationProvider Build(IConfigurationBuilder builder) { - return new JsonLocalizationConfigurationProvider(this); + var configurationProvider = new JsonLocalizationConfigurationProvider(this); + configurationProvider.Initialize(); + return configurationProvider; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs index b1fc601cb..ca811e127 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.Localization; public class LocalLocalizationResourceContributor : ILocalizationResourceContributor @@ -14,12 +15,11 @@ public class LocalLocalizationResourceContributor : ILocalizationResourceContrib public LocalLocalizationResourceContributor( Type resourceType, string cultureName, - IConfiguration configuration, - IMasaConfiguration? masaConfiguration = null) + IConfiguration configuration) { ResourceType = resourceType; CultureName = cultureName; - _configuration = masaConfiguration?.Local ?? configuration; + _configuration = configuration; } public string? GetOrNull(string name) @@ -27,7 +27,7 @@ public LocalLocalizationResourceContributor( var section = _configuration.GetSection(Const.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); if (section != null && section.Exists()) { - return section.GetValue(name); + return section.GetValue(name.Replace(".", ConfigurationPath.KeyDelimiter)); } return null; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationOptions.cs similarity index 62% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationOptions.cs index c84eb7856..c522c663b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Timing/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationOptions.cs @@ -1,3 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +namespace Masa.Contrib.Globalization.Localization; + +public class LocalizationOptions +{ + +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs deleted file mode 100644 index b7a88b532..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationResourceExtensions.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization; - -public static class LocalizationResourceExtensions -{ - private static readonly string _baseDirectory = AppDomain.CurrentDomain.BaseDirectory; - private static IConfiguration? _configuration; - private static IMasaConfiguration? _masaConfiguration; - - public static LocalizationResource AddJson( - this LocalizationResource localizationResource, - string languageDirectory) - { - languageDirectory.CheckIsNullOrWhiteSpace(); - - if (!Directory.Exists(languageDirectory)) - { - var path = Path.Combine(_baseDirectory, languageDirectory.TrimStart("/")); - if (!Directory.Exists(path)) - { - throw new UserFriendlyException($"[{languageDirectory}] does not exist"); - } - languageDirectory = path; - } - - var resources = GetResources(localizationResource, languageDirectory); - foreach (var resource in resources) - { - localizationResource.AddContributor(resource); - } - - return localizationResource; - } - - public static List GetResources( - LocalizationResource localizationResource, - string languageDirectory) - { - var filePaths = Directory.GetFiles(languageDirectory).ToList(); - - _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); - _masaConfiguration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); - - var services = MasaApp.GetServices(); - services.AddJsonLocalizationConfigurationSource(ref _configuration, _masaConfiguration, localizationResource.ResourceType, filePaths); - - return filePaths.Select - (filePath => (ILocalizationResourceContributor)new LocalLocalizationResourceContributor - ( - localizationResource.ResourceType, - LocalizationResourceConfiguration.Dictionary[filePath], - _configuration!, - _masaConfiguration - ) - ) - .ToList(); - } - - private static void AddJsonLocalizationConfigurationSource( - this IServiceCollection services, - ref IConfiguration? configuration, - IMasaConfiguration? masaConfiguration, - Type resourceType, - List filePaths) - { - ConfigurationManager configurationManager = new(); - if (configuration == null) - { - configuration = configurationManager; - services.AddSingleton(configurationManager); - } - else if (configuration is not ConfigurationManager) - { - configurationManager.AddConfiguration(configuration); - } - else if (configuration is ConfigurationManager configurationManagerTemp) - { - configurationManager = configurationManagerTemp; - } - var configurationBuilder = new ConfigurationBuilder(); - configurationBuilder.Add(new JsonLocalizationConfigurationSource(resourceType, filePaths, masaConfiguration != null)); - var localizationConfiguration = configurationBuilder.Build(); - configurationManager.AddConfiguration(localizationConfiguration); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj index 5f23e329a..4c6f0e5b2 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj @@ -1,16 +1,16 @@ - - net6.0 - enable - enable - + + net6.0 + enable + enable + - - - - - - + + + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs index a15067f0d..5fc7ddd80 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs @@ -6,26 +6,26 @@ namespace Masa.Contrib.Globalization.Localization; public class MasaStringLocalizer : IMasaStringLocalizer { private readonly LocalizationResource? _localizationResource; - private readonly IStringLocalizer? _stringLocalizer; - private readonly string _defaultCultureName; - public virtual string this[string name] => GetLocalizedString(name); + public string this[string name] => GetLocalizedString(name); - public virtual string this[string name, params object[] arguments] + public string this[string name, params object[] arguments] { get { ArgumentNullException.ThrowIfNull(name); var value = this[name]; - return string.Format(value, arguments); + return string.Format(CultureInfo.CurrentUICulture, value, arguments); } } - public MasaStringLocalizer(IStringLocalizerFactory? stringLocalizerFactory, IOptions options) + public string T(string name) => this[name]; + + public string T(string name, params object[] arguments) => this[name, arguments]; + + public MasaStringLocalizer(IOptions options) { - _stringLocalizer = stringLocalizerFactory?.Create(typeof(TResourceSource)); _localizationResource = options.Value.Resources.GetOrNull(); - _defaultCultureName = options.Value.DefaultCultureName; } private string GetLocalizedString(string name) @@ -35,20 +35,17 @@ private string GetLocalizedString(string name) { return resourceContributor.GetOrNull(name) ?? GetLocalizedStringByDefaultCultureName(name); } - if (_stringLocalizer != null) - { - return _stringLocalizer.GetString(name); - } throw new NotImplementedException(); } private string GetLocalizedStringByDefaultCultureName(string name) { - var resourceContributor = _localizationResource!.GetResourceContributor(new CultureInfo(_defaultCultureName)); - if (resourceContributor != null) + if (!LocalizationResourceConfiguration.DefaultCultureName.IsNullOrWhiteSpace()) { - return resourceContributor.GetOrNull(name) ?? name; + var resourceContributor = + _localizationResource!.GetResourceContributor(new CultureInfo(LocalizationResourceConfiguration.DefaultCultureName)); + return resourceContributor?.GetOrNull(name) ?? name; } - throw new NotImplementedException(); + return name; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs index 0272ab441..bec540cc1 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs @@ -3,6 +3,7 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Globalization.Localization; global using Masa.Contrib.Globalization.Localization; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs index 31c9c8b1d..37ed98389 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs @@ -7,76 +7,67 @@ namespace Masa.Contrib.Globalization.Localization.Tests; public class LocalizationResourceTest { [DataTestMethod] - [DataRow("zh-cn","吉姆")] - [DataRow("en","Jim")] + [DataRow("zh-CN", "吉姆")] + [DataRow("en-US", "Jim")] public void TestLocalization(string cultureName, string expectedValue) { var services = new ServiceCollection(); - services.Configure(masaLocalizationOptions => + services.AddLogging(); + services.TestAddMasaLocalization(options => { - masaLocalizationOptions.DefaultCultureName = "en"; - - masaLocalizationOptions.Resources - .Add() - .AddJson("/Resources"); + options.UseJson("Resources"); }); - services.AddLogging(); - services.AddMasaLocalization(); var serviceProvider = services.BuildServiceProvider(); CultureInfo.CurrentUICulture = new CultureInfo(cultureName); - var masaStringLocalizer = serviceProvider.GetRequiredService>(); - var value = masaStringLocalizer["Name"]; + var localizer = serviceProvider.GetRequiredService(); + var value = localizer["Name"]; + Assert.AreEqual(expectedValue, value); + value = localizer.T("Name"); Assert.AreEqual(expectedValue, value); - value = masaStringLocalizer["Name2"]; + value = localizer["Name2"]; Assert.AreEqual("Name2", value); } [DataTestMethod] - [DataRow("zh-cn","吉姆")] - [DataRow("en","Jim")] + [DataRow("zh-CN", "吉姆")] + [DataRow("en-US", "Jim")] public void TestLocalization2(string cultureName, string expectedValue) { var builder = WebApplication.CreateBuilder(); - builder.Services.Configure(masaLocalizationOptions => + builder.Services.TestAddMasaLocalization(options => { - masaLocalizationOptions.DefaultCultureName = "en"; - - masaLocalizationOptions.Resources - .Add() - .AddJson("/Resources"); + options.UseJson("Resources"); }); - builder.Services.AddMasaLocalization(); var serviceProvider = builder.Services.BuildServiceProvider(); CultureInfo.CurrentUICulture = new CultureInfo(cultureName); - var masaStringLocalizer = serviceProvider.GetRequiredService>(); - var value = masaStringLocalizer["Name"]; + var localizer = serviceProvider.GetRequiredService(); + var value = localizer["Name"]; + Assert.AreEqual(expectedValue, value); + value = localizer.T("Name"); Assert.AreEqual(expectedValue, value); - value = masaStringLocalizer["Name2"]; + value = localizer["Name2"]; Assert.AreEqual("Name2", value); } [DataTestMethod] - [DataRow("zh-cn","吉姆")] - [DataRow("en","Jim")] + [DataRow("zh-CN", "吉姆")] + [DataRow("en-US", "Jim")] public void TestLocalizationByMasaConfigurationLocal(string cultureName, string expectedValue) { var builder = WebApplication.CreateBuilder(); builder.Services.AddMasaConfiguration(); - builder.Services.Configure(masaLocalizationOptions => + builder.Services.TestAddMasaLocalization(options => { - masaLocalizationOptions.DefaultCultureName = "en"; - - masaLocalizationOptions.Resources - .Add() - .AddJson("/Resources"); + options.UseJson("Resources"); }); - builder.Services.AddMasaLocalization(); var serviceProvider = builder.Services.BuildServiceProvider(); CultureInfo.CurrentUICulture = new CultureInfo(cultureName); - var masaStringLocalizer = serviceProvider.GetRequiredService>(); - var value = masaStringLocalizer["Name"]; + var localizer = serviceProvider.GetRequiredService(); + var value = localizer["Name"]; + Assert.AreEqual(expectedValue, value); + value = localizer.T("Name"); Assert.AreEqual(expectedValue, value); - value = masaStringLocalizer["Name2"]; + value = localizer["Name2"]; Assert.AreEqual("Name2", value); } } diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj index 2598eb62d..7e1637b97 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj @@ -23,18 +23,23 @@ + - - - PreserveNewest + + + Always - - - PreserveNewest + + + Always + + + + Always diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en-US.json new file mode 100644 index 000000000..d7e013916 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en-US.json @@ -0,0 +1,6 @@ +{ + "Name": "Jim", + "User": { + "Name": "Jim2" + } +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json deleted file mode 100644 index 8a9921be6..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "en", - "texts": { - "Name": "Jim" - } -} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json new file mode 100644 index 000000000..6d67de6e2 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json @@ -0,0 +1,4 @@ +[ + "zh-CN", + "en-US" +] \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-CN.json new file mode 100644 index 000000000..c76dfe1f6 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-CN.json @@ -0,0 +1,6 @@ +{ + "Name": "吉姆", + "User": { + "Name": "Jim2" + } +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json deleted file mode 100644 index 50ae69e4f..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-Cn.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "zh-Cn", - "texts": { - "Name": "吉姆" - } -} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs index aee10b23f..3d6675751 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.Contrib.Globalization.Localization.Extensions; global using Microsoft.AspNetCore.Builder; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Localization; From a9fcf5ae6d647b5bb70fd8f26a0919cae4b32a20 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 19 Oct 2022 00:46:51 +0800 Subject: [PATCH 06/38] feat(Localization): Add Languages --- .../DefaultLanguageProvider.cs | 17 ++++++++++ .../ILanguageProvider.cs | 9 ++++++ .../LanguageInfo.cs | 19 +++++++++++ .../Options/MasaLocalizationOptions.cs | 5 ++- .../_Imports.cs | 3 ++ .../LocalizationOptionsExtensions.cs | 25 +++++++++++---- .../LocalizationResourceExtensions.cs | 8 ++--- .../Internal/Const.cs | 9 ++++++ .../_Imports.cs | 1 + .../LocalizationOptionsExtensions.cs | 19 +++++++++-- .../LocalizationResourceExtensions.cs | 32 ++++++------------- .../Extensions/ServiceCollectionExtensions.cs | 3 +- .../Resources/supportedCultures.json | 10 ++++-- 13 files changed, 122 insertions(+), 38 deletions(-) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/DefaultLanguageProvider.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILanguageProvider.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/DefaultLanguageProvider.cs new file mode 100644 index 000000000..04ce44023 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/DefaultLanguageProvider.cs @@ -0,0 +1,17 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.Localization; + +public class DefaultLanguageProvider : ILanguageProvider +{ + private readonly IOptionsMonitor _options; + + public DefaultLanguageProvider(IOptionsMonitor options) + { + _options = options; + } + + public IReadOnlyList GetLanguages() + => _options.CurrentValue.Languages; +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILanguageProvider.cs new file mode 100644 index 000000000..4d76e69ca --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILanguageProvider.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.Localization; + +public interface ILanguageProvider +{ + IReadOnlyList GetLanguages(); +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs new file mode 100644 index 000000000..e8ac09e81 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs @@ -0,0 +1,19 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.Localization; + +public class LanguageInfo +{ + public string Culture { get; set; } + + public string Display { get; set; } + + public string Icon { get; set; } + + public LanguageInfo(string culture, string? display = null) + { + Culture = culture; + Display = display ?? culture; + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs index 407d6e6a4..bb289ac32 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs @@ -8,10 +8,13 @@ public class MasaLocalizationOptions { public Type? DefaultResourceType { get; set; } + public List Languages { get; set; } + public LocalizationResourceDictionary Resources { get; } public MasaLocalizationOptions() { - Resources = new (); + Resources = new(); + Languages = new(); } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs index 97f7f6b77..c32bc696c 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs @@ -1,5 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Globalization.Localization; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Localization; +global using Microsoft.Extensions.Options; global using System.Globalization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs index 2724be1d2..ce0d932ed 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs @@ -8,27 +8,40 @@ public static class LocalizationOptionsExtensions { public static LocalizationOptions UseDcc( this LocalizationOptions localization, - params string[] cultureNames) - => localization.UseDcc(DccConfig.AppId, "I18n", cultureNames); + params LanguageInfo[] languages) + => localization.UseDcc(DccConfig.AppId, "I18n", languages); public static LocalizationOptions UseDcc( this LocalizationOptions localization, string configObject, - params string[] cultureNames) - => localization.UseDcc(DccConfig.AppId, configObject, cultureNames); + params LanguageInfo[] languages) + => localization.UseDcc(DccConfig.AppId, configObject, languages); public static LocalizationOptions UseDcc( this LocalizationOptions localization, string appId, string configObject, - params string[] cultureNames) + params LanguageInfo[] languages) { var services = MasaApp.GetServices(); services.Configure(options => { + if (languages.Length == 0) + { + var serviceProvider = services.BuildServiceProvider(); + var configurationApiClient = serviceProvider.GetRequiredService(); + languages = configurationApiClient.GetAsync>( + $"{configObject}.{Dcc.Internal.Const.SUPPORTED_CULTURES_FILE_NAME}", + newLanguages + => + { + options.Languages = newLanguages.ToList(); + }).ConfigureAwait(false).GetAwaiter().GetResult().ToArray(); + } + options.Languages = languages.ToList(); options.Resources .Add() - .UseDcc(appId, configObject, cultureNames); + .UseDcc(appId, configObject, languages); }); return localization; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs index abc39203f..cb2995edb 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs @@ -10,14 +10,14 @@ public static LocalizationResource UseDcc( this LocalizationResource localizationResource, string appId, string configObject, - params string[] cultureNames) + params LanguageInfo[] languages) { var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); var masaConfiguration = serviceProvider.GetRequiredService(); - foreach (var cultureName in cultureNames) + foreach (var language in languages) { - var resourceContributor = new DccLocalizationResourceContributor(appId, configObject, cultureName, masaConfiguration); - localizationResource.AddContributor(cultureName, resourceContributor); + var resourceContributor = new DccLocalizationResourceContributor(appId, configObject, language.Culture, masaConfiguration); + localizationResource.AddContributor(language.Culture, resourceContributor); } return localizationResource; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs new file mode 100644 index 000000000..7df7f1011 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.Localization.Dcc.Internal; + +internal static class Const +{ + internal const string SUPPORTED_CULTURES_FILE_NAME = "supportedCultures.json"; +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs index f33e0a245..8533beb1f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs @@ -3,6 +3,7 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Globalization.Localization; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; global using Masa.Contrib.Globalization.Localization.Dcc; global using Microsoft.Extensions.Configuration; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs index 039f0122e..38d76ef6d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs @@ -7,14 +7,29 @@ public static class MasaLocalizationOptionsExtensions { public static void UseJson(this LocalizationOptions _, string languageDirectory, - params string[] cultureNames) + params LanguageInfo[] languages) { var services = MasaApp.GetServices(); + if (languages.Length == 0) + languages = GetLanguageInfos(languageDirectory).ToArray(); + services.Configure(options => { + options.Languages = languages.ToList(); + options.Resources .Add() - .AddJson(languageDirectory, cultureNames); + .AddJson(languageDirectory, languages); }); } + + private static List GetLanguageInfos(string languageDirectory) + { + var supportCultureFilePath = Path.Combine(languageDirectory, Internal.Const.SUPPORTED_CULTURES_FILE_NAME); + var content = File.ReadAllText(supportCultureFilePath); + return System.Text.Json.JsonSerializer.Deserialize>(content) ?? new List() + { + new("en-US") + }; + } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs index 1b17d7535..377e3117d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs @@ -13,17 +13,13 @@ public static class LocalizationResourceExtensions public static LocalizationResource AddJson( this LocalizationResource localizationResource, string languageDirectory, - params string[] cultureNames) + params LanguageInfo[] languages) { languageDirectory = GetAndCheckLanguageDirectory(languageDirectory); - if (cultureNames.Length == 0) - { - cultureNames = GetCultureNames(languageDirectory).ToArray(); - } var resourceContributors = GetResourceContributors( localizationResource, languageDirectory, - cultureNames); + languages); foreach (var resourceContributor in resourceContributors) { localizationResource.AddContributor(resourceContributor.CultureName, resourceContributor); @@ -52,20 +48,12 @@ private static string GetAndCheckLanguageDirectory(string languageDirectory) return languageDirectory; } - private static List GetCultureNames(string languageDirectory) - { - var supportCultureFilePath = Path.Combine(languageDirectory, Internal.Const.SUPPORTED_CULTURES_FILE_NAME); - var content = File.ReadAllText(supportCultureFilePath); - return System.Text.Json.JsonSerializer.Deserialize>(content) ?? new List() - { - "en-US" - }; - } + private static List GetResourceContributors( LocalizationResource localizationResource, string languageDirectory, - IEnumerable cultureNames) + IEnumerable languages) { _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); _masaConfiguration ??= @@ -78,17 +66,17 @@ private static List GetResourceContributors( var useMasaConfiguration = _masaConfiguration != null; services.AddJsonLocalizationConfigurationSource( languageDirectory, - cultureNames, + languages, localizationResource.ResourceType, ref configuration, useMasaConfiguration); _configuration = configuration; - return cultureNames.Select - (cultureName => (ILocalizationResourceContributor)new LocalLocalizationResourceContributor + return languages.Select + (languageInfo => (ILocalizationResourceContributor)new LocalLocalizationResourceContributor ( localizationResource.ResourceType, - cultureName, + languageInfo.Culture, useMasaConfiguration ? _configuration!.GetSection(SectionTypes.Local.ToString()) : _configuration! ) ) @@ -98,7 +86,7 @@ private static List GetResourceContributors( private static void AddJsonLocalizationConfigurationSource( this IServiceCollection services, string languageDirectory, - IEnumerable cultureNames, + IEnumerable languages, Type resourceType, ref IConfiguration? configuration, bool useMasaConfiguration) @@ -119,7 +107,7 @@ private static void AddJsonLocalizationConfigurationSource( } var configurationBuilder = new ConfigurationBuilder(); var jsonLocalizationConfigurationSource = - new JsonLocalizationConfigurationSource(resourceType, languageDirectory, cultureNames, useMasaConfiguration); + new JsonLocalizationConfigurationSource(resourceType, languageDirectory, languages.Select(l=>l.Culture), useMasaConfiguration); configurationBuilder.Add(jsonLocalizationConfigurationSource); var localizationConfiguration = configurationBuilder.Build(); configurationManager.AddConfiguration(localizationConfiguration); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs index 9c9100aa6..516f0a070 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs @@ -31,7 +31,8 @@ private static IServiceCollection AddMasaLocalizationCore(this IServiceCollectio options.DefaultResourceType ??= typeof(DefaultResource); }); services.TryAddSingleton(typeof(IMasaStringLocalizer<>), typeof(MasaStringLocalizer<>)); - services.AddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); action?.Invoke(new Masa.Contrib.Globalization.Localization.LocalizationOptions()); diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json index 6d67de6e2..c334e66de 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json @@ -1,4 +1,10 @@ [ - "zh-CN", - "en-US" + { + "Culture": "zh-CN", + "Display": "中文简体" + }, + { + "Culture": "en-US", + "Display": "English (United States)" + } ] \ No newline at end of file From 73faafff9c0185401186fd961780f94ea73dcc28 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 19 Oct 2022 15:33:42 +0800 Subject: [PATCH 07/38] chore: global using --- .../MasaConfigurationExtensions.cs | 3 --- .../_Imports.cs | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs index 0c181281f..3d78728ed 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs @@ -2,9 +2,6 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace - -using Masa.Contrib.Configuration.ConfigurationApi.Dcc; - namespace Masa.BuildingBlocks.Configuration; public static class MasaConfigurationExtensions diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/_Imports.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/_Imports.cs index a54a0a0b7..1b218e69e 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/_Imports.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/_Imports.cs @@ -9,6 +9,7 @@ global using Masa.BuildingBlocks.Service.Caller.Options; global using Masa.Contrib.Caching.Distributed.StackExchangeRedis; global using Masa.Contrib.Caching.MultilevelCache; +global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc.Internal; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc.Internal.Model; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc.Internal.Parser; From ab36063ada4af8fc5dc5f04d45dea5db52def9db Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 19 Oct 2022 18:24:20 +0800 Subject: [PATCH 08/38] feat: Add I18N --- Masa.Framework.sln | 8 +- .../Const.cs | 4 +- .../DefaultLanguageProvider.cs | 6 +- .../I18NResource.cs} | 13 ++- .../I18NResourceDictionary.cs | 31 ++++++ .../I18NResourceResourceConfiguration.cs} | 4 +- .../II18N.cs} | 10 +- .../II18NOfT.cs | 9 ++ .../II18NResourceContributor.cs} | 5 +- .../ILanguageProvider.cs | 2 +- .../LanguageInfo.cs | 4 +- ...a.BuildingBlocks.Globalization.I18N.csproj | 13 +++ .../Options/MasaI18NOptions.cs} | 8 +- .../_Imports.cs | 3 - .../IMasaStringLocalizerFactory.cs | 12 --- .../IMasaStringLocalizerOfT.cs | 10 -- .../LocalizationResourceDictionary.cs | 32 ------- ...ngBlocks.Globalization.Localization.csproj | 14 --- .../MasaStringLocalizerFactory.cs | 24 ----- .../DccLocalizationResourceContributor.cs | 6 +- .../Extensions/I18NOptionsExtensions.cs} | 23 ++--- .../Extensions/I18NResourceExtensions.cs} | 15 +-- .../Internal/Const.cs | 9 ++ ...Masa.Contrib.Globalization.I18N.Dcc.csproj | 15 +++ .../_Imports.cs | 5 +- .../DefaultResource.cs | 4 +- .../Extensions/I18NOptionsExtensions.cs | 68 ++++++++++++++ .../Extensions/I18NResourceExtensions.cs} | 68 +++++--------- .../Extensions/ServiceCollectionExtensions.cs | 44 +++++++++ .../FileLocalizationConfigurationProvider.cs | 9 +- .../I18NOfT.cs | 55 +++++++++++ .../I18NOptions.cs} | 5 +- .../Internal/Const.cs | 11 +++ .../Internal/PathHelper.cs | 20 ++++ .../JsonLocalizationConfigurationProvider.cs | 3 +- .../JsonLocalizationConfigurationSource.cs | 4 +- .../LocalI18NResourceContributor.cs} | 7 +- .../Masa.Contrib.Globalization.I18N.csproj} | 2 +- .../_Imports.cs | 7 +- .../Internal/Const.cs | 9 -- ...trib.Globalization.Localization.Dcc.csproj | 15 --- .../LocalizationOptionsExtensions.cs | 35 ------- .../Extensions/ServiceCollectionExtensions.cs | 44 --------- .../Internal/Const.cs | 9 -- .../MasaStringLocalizerOfT.cs | 51 ---------- .../I18NTest.cs | 94 +++++++++++++++++++ ...a.Contrib.Globalization.I18N.Tests.csproj} | 15 +-- .../Resources/en-US.json | 0 .../Resources/supportedCultures.json | 0 .../Resources/zh-CN.json | 0 .../_Imports.cs | 3 +- .../LocalizationResourceTest.cs | 73 -------------- 52 files changed, 471 insertions(+), 469 deletions(-) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization => Masa.BuildingBlocks.Globalization.I18N}/Const.cs (59%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization => Masa.BuildingBlocks.Globalization.I18N}/DefaultLanguageProvider.cs (62%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs => Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs} (62%) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs => Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs} (72%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs => Masa.BuildingBlocks.Globalization.I18N/II18N.cs} (84%) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs => Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs} (62%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization => Masa.BuildingBlocks.Globalization.I18N}/ILanguageProvider.cs (80%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization => Masa.BuildingBlocks.Globalization.I18N}/LanguageInfo.cs (80%) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs => Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs} (67%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.Localization => Masa.BuildingBlocks.Globalization.I18N}/_Imports.cs (57%) delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/DccLocalizationResourceContributor.cs (80%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs => Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs} (72%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs => Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs} (52%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/_Imports.cs (70%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization => Masa.Contrib.Globalization.I18N}/DefaultResource.cs (76%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs => Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs} (57%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization => Masa.Contrib.Globalization.I18N}/FileLocalizationConfigurationProvider.cs (89%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization/LocalizationOptions.cs => Masa.Contrib.Globalization.I18N/I18NOptions.cs} (64%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization => Masa.Contrib.Globalization.I18N}/Json/JsonLocalizationConfigurationProvider.cs (88%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization => Masa.Contrib.Globalization.I18N}/Json/JsonLocalizationConfigurationSource.cs (91%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs => Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs} (83%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj => Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj} (85%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.Localization => Masa.Contrib.Globalization.I18N}/_Imports.cs (72%) delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj => Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj} (70%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.Localization.Tests => Masa.Contrib.Globalization.I18N.Tests}/Resources/en-US.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.Localization.Tests => Masa.Contrib.Globalization.I18N.Tests}/Resources/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.Localization.Tests => Masa.Contrib.Globalization.I18N.Tests}/Resources/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.Localization.Tests => Masa.Contrib.Globalization.I18N.Tests}/_Imports.cs (74%) delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index ef0a1d066..4182d50db 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -575,19 +575,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalizat EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Service.Caller.Authentication.OpenIdConnect", "src\Contrib\Service\Caller\Authentication\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.csproj", "{9BB5CC86-C2E8-4859-9610-50DB263605A3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.Localization", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.Localization\Masa.BuildingBlocks.Globalization.Localization.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.I18N", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18N\Masa.BuildingBlocks.Globalization.I18N.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests", "src\Contrib\Service\Caller\Authentication\Tests\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests.csproj", "{BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization", "src\Contrib\Globalization\Masa.Contrib.Globalization.Localization\Masa.Contrib.Globalization.Localization.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N\Masa.Contrib.Globalization.I18N.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D2E598D5-5E44-4275-AF03-4BAD07A0E13B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.Localization.Tests\Masa.Contrib.Globalization.Localization.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Tests\Masa.Contrib.Globalization.I18N.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.Localization.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.Localization.Dcc\Masa.Contrib.Globalization.Localization.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Dcc\Masa.Contrib.Globalization.I18N.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Const.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Const.cs similarity index 59% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Const.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Const.cs index a16c8122d..03880d93e 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Const.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Const.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; public static class Const { - public const string DEFAULT_LOCAL_SECTION = "Localization"; + public const string DEFAULT_LOCAL_SECTION = "I18N"; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs similarity index 62% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/DefaultLanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs index 04ce44023..b1d0bb9cd 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/DefaultLanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs @@ -1,13 +1,13 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; public class DefaultLanguageProvider : ILanguageProvider { - private readonly IOptionsMonitor _options; + private readonly IOptionsMonitor _options; - public DefaultLanguageProvider(IOptionsMonitor options) + public DefaultLanguageProvider(IOptionsMonitor options) { _options = options; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs similarity index 62% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs index d9469bd71..b96bce990 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs @@ -1,22 +1,21 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; -public class LocalizationResource +public class I18NResource { - private readonly Dictionary _dictionary; + private readonly Dictionary _dictionary; public Type ResourceType { get; } - public LocalizationResource(Type resourceType) + public I18NResource(Type resourceType) { _dictionary = new(StringComparer.OrdinalIgnoreCase); ResourceType = resourceType; } - public void AddContributor(string cultureName,ILocalizationResourceContributor localizationResourceContributor) + public void AddContributor(string cultureName,II18NResourceContributor localizationResourceContributor) { if (_dictionary.ContainsKey(cultureName)) throw new ArgumentException($"The {cultureName} already exists with {ResourceType.FullName}"); @@ -24,7 +23,7 @@ public void AddContributor(string cultureName,ILocalizationResourceContributor l _dictionary.Add(localizationResourceContributor.CultureName, localizationResourceContributor); } - public ILocalizationResourceContributor? GetResourceContributor(CultureInfo? cultureInfo = null) + public II18NResourceContributor? GetResourceContributor(CultureInfo? cultureInfo = null) { var cultureName = cultureInfo?.Name ?? CultureInfo.CurrentUICulture.Name; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs new file mode 100644 index 000000000..28b589080 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs @@ -0,0 +1,31 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +[Serializable] +public class I18NResourceDictionary : Dictionary +{ + public I18NResource Add() + { + return Add(typeof(TResource)); + } + + public I18NResource Add(Type resourceType) + { + if (ContainsKey(resourceType)) + throw new ArgumentException("This resource is already added before: " + resourceType.FullName); + + return this[resourceType] = new I18NResource(resourceType); + } + + public I18NResource? GetOrNull(Type resourceType) + { + if (!ContainsKey(resourceType)) + return null; + + return this[resourceType]; + } + + public I18NResource? GetOrNull() => GetOrNull(typeof(TResource)); +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs similarity index 72% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs index 07d81fe1e..b4cdd8de4 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceConfiguration.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; -public static class LocalizationResourceConfiguration +public static class I18NResourceResourceConfiguration { public static readonly string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs similarity index 84% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs index b2b063022..549eb6cda 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizer.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs @@ -1,11 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace +namespace Masa.BuildingBlocks.Globalization.I18N; -namespace Microsoft.Extensions.Localization; - -public interface IMasaStringLocalizer +public interface II18N { /// Gets the string resource with the given name. /// The name of the string resource. @@ -23,4 +21,8 @@ public interface IMasaStringLocalizer string T(string name); string T(string name, params object[] arguments); + + void SetCulture(string cultureName, bool useUserOverride = true); + + void SetCulture(CultureInfo culture); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs new file mode 100644 index 000000000..0a32bf50c --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +public interface II18N : II18N +{ + +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs similarity index 62% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs index 571d88e31..88a700380 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILocalizationResourceContributor.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs @@ -1,10 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; -public interface ILocalizationResourceContributor +public interface II18NResourceContributor { string CultureName { get; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs similarity index 80% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs index 4d76e69ca..1c0c8d806 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/ILanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; public interface ILanguageProvider { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs similarity index 80% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs index e8ac09e81..75763f9e7 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LanguageInfo.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs @@ -1,10 +1,12 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; public class LanguageInfo { + public bool DefaultCulture { get; set; } = false; + public string Culture { get; set; } public string Display { get; set; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj new file mode 100644 index 000000000..b3d41f5ba --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs similarity index 67% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs index bb289ac32..3cbcc94e6 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Options/MasaLocalizationOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs @@ -2,17 +2,17 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Localization; +namespace Masa.BuildingBlocks.Globalization.I18N; -public class MasaLocalizationOptions +public class MasaI18NOptions { public Type? DefaultResourceType { get; set; } public List Languages { get; set; } - public LocalizationResourceDictionary Resources { get; } + public I18NResourceDictionary Resources { get; } - public MasaLocalizationOptions() + public MasaI18NOptions() { Resources = new(); Languages = new(); diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs similarity index 57% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index c32bc696c..b51383891 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -1,8 +1,5 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.BuildingBlocks.Globalization.Localization; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Localization; global using Microsoft.Extensions.Options; global using System.Globalization; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs deleted file mode 100644 index 02aa5b95c..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerFactory.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Localization; - -public interface IMasaStringLocalizerFactory -{ - IMasaStringLocalizer Create(); - - IMasaStringLocalizer Create(Type resourceSource); -} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs deleted file mode 100644 index 93b116cd4..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/IMasaStringLocalizerOfT.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Localization; - -public interface IMasaStringLocalizer : IMasaStringLocalizer -{ - -} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs deleted file mode 100644 index 8c2096992..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/LocalizationResourceDictionary.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Localization; - -[Serializable] -public class LocalizationResourceDictionary : Dictionary -{ - public LocalizationResource Add() - { - return Add(typeof(TResource)); - } - - public LocalizationResource Add(Type resourceType) - { - if (ContainsKey(resourceType)) - throw new ArgumentException("This resource is already added before: " + resourceType.FullName); - - return this[resourceType] = new LocalizationResource(resourceType); - } - - public LocalizationResource? GetOrNull(Type resourceType) - { - if (!ContainsKey(resourceType)) - return null; - - return this[resourceType]; - } - - public LocalizationResource? GetOrNull() => GetOrNull(typeof(TResource)); -} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj deleted file mode 100644 index f9507c745..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/Masa.BuildingBlocks.Globalization.Localization.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net6.0 - enable - enable - Masa.BuildingBlocks.Globalization.Localization - - - - - - - diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs deleted file mode 100644 index 69cc02e60..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.Localization/MasaStringLocalizerFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Localization; - -public class MasaStringLocalizerFactory : IMasaStringLocalizerFactory -{ - private readonly IServiceProvider _serviceProvider; - - public MasaStringLocalizerFactory(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public IMasaStringLocalizer Create() - => _serviceProvider.GetRequiredService>(); - - public IMasaStringLocalizer Create(Type resourceSource) - { - var serviceType = typeof(IMasaStringLocalizer<>).MakeGenericType(resourceSource); - return (IMasaStringLocalizer)_serviceProvider.GetRequiredService(serviceType); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccLocalizationResourceContributor.cs similarity index 80% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccLocalizationResourceContributor.cs index 8226c05a2..d625d27fb 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/DccLocalizationResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccLocalizationResourceContributor.cs @@ -1,15 +1,15 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.Localization.Dcc; +namespace Masa.Contrib.Globalization.I18N.Dcc; -public class DccLocalizationResourceContributor : ILocalizationResourceContributor +public class DccI18NResourceContributor : II18NResourceContributor { private readonly IConfigurationSection _configurationSection; public string CultureName { get; } - public DccLocalizationResourceContributor( + public DccI18NResourceContributor( string appId, string configObject, string cultureName, diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs similarity index 72% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index ce0d932ed..560a4c5b1 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -1,37 +1,38 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.Localization; -public static class LocalizationOptionsExtensions +namespace Masa.Contrib.Globalization.I18N; + +public static class I18NOptionsExtensions { - public static LocalizationOptions UseDcc( - this LocalizationOptions localization, + public static I18NOptions UseDcc( + this I18NOptions localization, params LanguageInfo[] languages) => localization.UseDcc(DccConfig.AppId, "I18n", languages); - public static LocalizationOptions UseDcc( - this LocalizationOptions localization, + public static I18NOptions UseDcc( + this I18NOptions localization, string configObject, params LanguageInfo[] languages) => localization.UseDcc(DccConfig.AppId, configObject, languages); - public static LocalizationOptions UseDcc( - this LocalizationOptions localization, + public static I18NOptions UseDcc( + this I18NOptions localization, string appId, string configObject, params LanguageInfo[] languages) { var services = MasaApp.GetServices(); - services.Configure(options => + services.Configure(options => { if (languages.Length == 0) { var serviceProvider = services.BuildServiceProvider(); var configurationApiClient = serviceProvider.GetRequiredService(); languages = configurationApiClient.GetAsync>( - $"{configObject}.{Dcc.Internal.Const.SUPPORTED_CULTURES_FILE_NAME}", + $"{configObject}.{Dcc.Internal.Const.SUPPORTED_CULTURES_NAME}", newLanguages => { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs similarity index 52% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs index cb2995edb..2cc5c9444 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Extensions/LocalizationResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs @@ -2,22 +2,23 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.Localization; -public static class LocalizationResourceExtensions +namespace Masa.BuildingBlocks.Globalization.I18N; + +public static class I18NResourceExtensions { - public static LocalizationResource UseDcc( - this LocalizationResource localizationResource, + public static I18NResource UseDcc( + this I18NResource localizationResource, string appId, string configObject, params LanguageInfo[] languages) { var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); var masaConfiguration = serviceProvider.GetRequiredService(); - foreach (var language in languages) + var contributors = languages.Select(language => new DccI18NResourceContributor(appId, configObject, language.Culture, masaConfiguration)).ToList(); + foreach (var contributor in contributors) { - var resourceContributor = new DccLocalizationResourceContributor(appId, configObject, language.Culture, masaConfiguration); - localizationResource.AddContributor(language.Culture, resourceContributor); + localizationResource.AddContributor(contributor.CultureName, contributor); } return localizationResource; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs new file mode 100644 index 000000000..b952c6e0b --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Dcc.Internal; + +internal static class Const +{ + internal const string SUPPORTED_CULTURES_NAME = "supportedCultures"; +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj new file mode 100644 index 000000000..25efebcc9 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + enable + enable + + + + + + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs similarity index 70% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs index 8533beb1f..5a8d83f3b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs @@ -3,9 +3,8 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Globalization.Localization; +global using Masa.BuildingBlocks.Globalization.I18N; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; -global using Masa.Contrib.Globalization.Localization.Dcc; +global using Masa.Contrib.Globalization.I18N.Dcc; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Localization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/DefaultResource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/DefaultResource.cs similarity index 76% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/DefaultResource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/DefaultResource.cs index edfed412e..23bed80da 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/DefaultResource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/DefaultResource.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.Localization; +namespace Masa.Contrib.Globalization.I18N; public class DefaultResource { - + } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs new file mode 100644 index 000000000..325093636 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs @@ -0,0 +1,68 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +using Microsoft.Extensions.FileProviders; + +namespace Masa.Contrib.Globalization.I18N; + +public static class I18NOptionsExtensions +{ + public static void UseJson(this I18NOptions _, + params LanguageInfo[] languages) + => _.UseJson(Internal.Const.DEFAULT_RESOURCE_PATH, Internal.Const.SUPPORTED_CULTURES_NAME, languages); + + public static void UseJson(this I18NOptions _, + string languageDirectory, + params LanguageInfo[] languages) + => _.UseJson(languageDirectory, Internal.Const.SUPPORTED_CULTURES_NAME, languages); + + public static void UseJson(this I18NOptions _, + string languageDirectory, + string supportCultureName, + params LanguageInfo[] languages) + { + var services = MasaApp.GetServices(); + + languageDirectory = PathHelper.GetAndCheckLanguageDirectory(languageDirectory); + + if (languages.Length == 0) + { + languages = GetLanguageInfos(languageDirectory, supportCultureName).ToArray(); + MonitorChange(languageDirectory, supportCultureName, () => + { + var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + options.Value.Languages = GetLanguageInfos(languageDirectory, supportCultureName).ToList(); + }); + } + + services.Configure(options => + { + options.Languages = languages.ToList(); + + options.Resources + .Add() + .AddJson(languageDirectory, languages); + }); + } + + private static List GetLanguageInfos( + string languageDirectory, + string supportCultureName) + { + var supportCultureFilePath = Path.Combine(languageDirectory, supportCultureName); + var content = File.ReadAllText(supportCultureFilePath); + return System.Text.Json.JsonSerializer.Deserialize>(content)!; + } + + private static void MonitorChange(string filePath, string supportCultureName, Action onChange) + { + var fileProvider = new PhysicalFileProvider(filePath); + ChangeToken.OnChange( + () => fileProvider.Watch(supportCultureName), + onChange + ); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs similarity index 57% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index 377e3117d..339323ed9 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -2,56 +2,35 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.Localization; -public static class LocalizationResourceExtensions +namespace Masa.BuildingBlocks.Globalization.I18N; + +public static class I18NResourceExtensions { private static IConfiguration? _configuration; private static IMasaConfiguration? _masaConfiguration; - public static LocalizationResource AddJson( - this LocalizationResource localizationResource, + public static I18NResource AddJson( + this I18NResource resource, string languageDirectory, params LanguageInfo[] languages) { - languageDirectory = GetAndCheckLanguageDirectory(languageDirectory); + languageDirectory = PathHelper.GetAndCheckLanguageDirectory(languageDirectory); var resourceContributors = GetResourceContributors( - localizationResource, + resource, languageDirectory, languages); foreach (var resourceContributor in resourceContributors) { - localizationResource.AddContributor(resourceContributor.CultureName, resourceContributor); + resource.AddContributor(resourceContributor.CultureName, resourceContributor); } - return localizationResource; + return resource; } - private static string GetAndCheckLanguageDirectory(string languageDirectory) - { - languageDirectory.CheckIsNullOrWhiteSpace(); - - if (!Directory.Exists(languageDirectory)) - { - var path = Path.Combine(LocalizationResourceConfiguration.BaseDirectory, languageDirectory.TrimStart("/")); - if (!Directory.Exists(path)) - { - throw new UserFriendlyException($"[{languageDirectory}] does not exist"); - } - languageDirectory = path; - } - else - { - languageDirectory = Path.GetFullPath(languageDirectory); - } - return languageDirectory; - } - - - - private static List GetResourceContributors( - LocalizationResource localizationResource, + private static List GetResourceContributors( + I18NResource resource, string languageDirectory, IEnumerable languages) { @@ -60,22 +39,19 @@ private static List GetResourceContributors( MasaApp.GetServices().BuildServiceProvider().GetService(); var services = MasaApp.GetServices(); - - var configuration = _configuration; - var useMasaConfiguration = _masaConfiguration != null; - services.AddJsonLocalizationConfigurationSource( + var configuration = AddJsonConfigurationSource( + services, languageDirectory, languages, - localizationResource.ResourceType, - ref configuration, + resource.ResourceType, + _configuration, useMasaConfiguration); _configuration = configuration; - return languages.Select - (languageInfo => (ILocalizationResourceContributor)new LocalLocalizationResourceContributor + return languages.Select(languageInfo => (II18NResourceContributor)new LocalI18NResourceContributor ( - localizationResource.ResourceType, + resource.ResourceType, languageInfo.Culture, useMasaConfiguration ? _configuration!.GetSection(SectionTypes.Local.ToString()) : _configuration! ) @@ -83,12 +59,12 @@ private static List GetResourceContributors( .ToList(); } - private static void AddJsonLocalizationConfigurationSource( - this IServiceCollection services, + private static IConfiguration AddJsonConfigurationSource( + IServiceCollection services, string languageDirectory, IEnumerable languages, Type resourceType, - ref IConfiguration? configuration, + IConfiguration? configuration, bool useMasaConfiguration) { ConfigurationManager configurationManager = new(); @@ -107,9 +83,11 @@ private static void AddJsonLocalizationConfigurationSource( } var configurationBuilder = new ConfigurationBuilder(); var jsonLocalizationConfigurationSource = - new JsonLocalizationConfigurationSource(resourceType, languageDirectory, languages.Select(l=>l.Culture), useMasaConfiguration); + new JsonLocalizationConfigurationSource(resourceType, languageDirectory, languages.Select(l => l.Culture), + useMasaConfiguration); configurationBuilder.Add(jsonLocalizationConfigurationSource); var localizationConfiguration = configurationBuilder.Build(); configurationManager.AddConfiguration(localizationConfiguration); + return configuration; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..e9c7aac62 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,44 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.Extensions.DependencyInjection; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddI18N( + this IServiceCollection services, + Action? action) + { + MasaApp.TrySetServiceCollection(services); + return services.AddI18NCore(action); + } + + public static IServiceCollection TestAddI18N( + this IServiceCollection services, + Action? action) + { + MasaApp.SetServiceCollection(services); + return services.AddI18NCore(action); + } + + private static IServiceCollection AddI18NCore( + this IServiceCollection services, + Action? action) + { + services.Configure(options => + { + options.DefaultResourceType ??= typeof(DefaultResource); + }); + services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); + services.TryAddSingleton(); + + action?.Invoke(new I18NOptions()); + + var masaLocalizationOptions = services.BuildServiceProvider().GetRequiredService>().Value; + var defaultResourceLocalizer = typeof(II18N<>).MakeGenericType(masaLocalizationOptions.DefaultResourceType!); + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService(defaultResourceLocalizer)); + return services; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileLocalizationConfigurationProvider.cs similarity index 89% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileLocalizationConfigurationProvider.cs index 8b3374612..95af8bda9 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/FileLocalizationConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileLocalizationConfigurationProvider.cs @@ -1,7 +1,7 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.Localization; +namespace Masa.Contrib.Globalization.I18N; public abstract class FileLocalizationConfigurationProvider : ConfigurationProvider { @@ -25,11 +25,6 @@ public override void Load() foreach (var cultureName in _cultureNames) { var configuration = InitializeConfiguration(_languageDirectory, cultureName); - if (configuration.GetSection("$DefaultCulture").Exists() && configuration.GetValue("$DefaultCulture")) - { - LocalizationResourceConfiguration.DefaultCultureName = cultureName; - } - _dictionary[FormatKey(cultureName)] = configuration.ConvertToDictionary(); } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs new file mode 100644 index 000000000..8405d3484 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs @@ -0,0 +1,55 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N; + +public class I18N : II18N +{ + private readonly I18NResource? _resource; + public string this[string name] => T(name); + + public string this[string name, params object[] arguments] => T(name, arguments); + + public I18N(IOptions options) + { + _resource = options.Value.Resources.GetOrNull(); + } + + public string T(string name) + { + var resourceContributor = _resource?.GetResourceContributor(CultureInfo.CurrentUICulture); + if (resourceContributor != null) + { + return resourceContributor.GetOrNull(name) ?? GetLocalizedStringByDefaultCultureName(name); + } + + return name; + } + + public string T(string name, params object[] arguments) + { + ArgumentNullException.ThrowIfNull(name); + + var value = this[name]; + return string.Format(CultureInfo.CurrentUICulture, value, arguments); + } + + public void SetCulture(string cultureName, bool useUserOverride = true) + => SetCulture(new CultureInfo(cultureName, useUserOverride)); + + public virtual void SetCulture(CultureInfo culture) + { + CultureInfo.DefaultThreadCurrentUICulture = culture; + } + + private string GetLocalizedStringByDefaultCultureName(string name) + { + if (!I18NResourceResourceConfiguration.DefaultCultureName.IsNullOrWhiteSpace()) + { + var resourceContributor = + _resource!.GetResourceContributor(new CultureInfo(I18NResourceResourceConfiguration.DefaultCultureName)); + return resourceContributor?.GetOrNull(name) ?? name; + } + return name; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationOptions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOptions.cs similarity index 64% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationOptions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOptions.cs index c522c663b..22be9b825 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalizationOptions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOptions.cs @@ -1,9 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.Localization; +namespace Masa.Contrib.Globalization.I18N; -public class LocalizationOptions +public class I18NOptions { - } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs new file mode 100644 index 000000000..9e906b1fd --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Internal; + +internal static class Const +{ + internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; + + internal const string DEFAULT_RESOURCE_PATH = "Resources"; +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs new file mode 100644 index 000000000..b788c0a75 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.I18N; + +internal static class PathHelper +{ + internal static string GetAndCheckLanguageDirectory(string languageDirectory) + { + languageDirectory.CheckIsNullOrWhiteSpace(); + var path = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, languageDirectory.TrimStart("/")); + if (!Directory.Exists(path)) + { + throw new UserFriendlyException($"[{languageDirectory}] does not exist"); + } + + return path; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationProvider.cs similarity index 88% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationProvider.cs index 35b651b46..a83c52174 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationProvider.cs @@ -1,8 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.Localization; +namespace Masa.Contrib.Globalization.I18N.Json; public class JsonLocalizationConfigurationProvider : FileLocalizationConfigurationProvider { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationSource.cs similarity index 91% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationSource.cs index eb22eb37b..1120707f0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Json/JsonLocalizationConfigurationSource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationSource.cs @@ -1,9 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace - -namespace Masa.Contrib.Globalization.Localization; +namespace Masa.Contrib.Globalization.I18N.Json; public class JsonLocalizationConfigurationSource : IConfigurationSource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs similarity index 83% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs index ca811e127..68a3fb788 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/LocalLocalizationResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs @@ -1,10 +1,11 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + namespace Microsoft.Extensions.Localization; -public class LocalLocalizationResourceContributor : ILocalizationResourceContributor +public class LocalI18NResourceContributor : II18NResourceContributor { private readonly IConfiguration _configuration; @@ -12,7 +13,7 @@ public class LocalLocalizationResourceContributor : ILocalizationResourceContrib public string CultureName { get; } - public LocalLocalizationResourceContributor( + public LocalI18NResourceContributor( Type resourceType, string cultureName, IConfiguration configuration) diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj similarity index 85% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index 4c6f0e5b2..07afb0cda 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Masa.Contrib.Globalization.Localization.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs similarity index 72% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index bec540cc1..baf0f7ab7 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -1,10 +1,11 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Globalization.Localization; -global using Masa.Contrib.Globalization.Localization; +global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.Contrib.Globalization.I18N; +global using Masa.Contrib.Globalization.I18N.Json; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs deleted file mode 100644 index 7df7f1011..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Internal/Const.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization.Dcc.Internal; - -internal static class Const -{ - internal const string SUPPORTED_CULTURES_FILE_NAME = "supportedCultures.json"; -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj deleted file mode 100644 index 8e57ba66d..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization.Dcc/Masa.Contrib.Globalization.Localization.Dcc.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs deleted file mode 100644 index 38d76ef6d..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/LocalizationOptionsExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization.Extensions; - -public static class MasaLocalizationOptionsExtensions -{ - public static void UseJson(this LocalizationOptions _, - string languageDirectory, - params LanguageInfo[] languages) - { - var services = MasaApp.GetServices(); - if (languages.Length == 0) - languages = GetLanguageInfos(languageDirectory).ToArray(); - - services.Configure(options => - { - options.Languages = languages.ToList(); - - options.Resources - .Add() - .AddJson(languageDirectory, languages); - }); - } - - private static List GetLanguageInfos(string languageDirectory) - { - var supportCultureFilePath = Path.Combine(languageDirectory, Internal.Const.SUPPORTED_CULTURES_FILE_NAME); - var content = File.ReadAllText(supportCultureFilePath); - return System.Text.Json.JsonSerializer.Deserialize>(content) ?? new List() - { - new("en-US") - }; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs deleted file mode 100644 index 516f0a070..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Extensions/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Microsoft.Extensions.DependencyInjection; - -public static class ServiceCollectionExtensions -{ - public static IServiceCollection AddMasaLocalization( - this IServiceCollection services, - Action? action) - { - MasaApp.TrySetServiceCollection(services); - return services.AddMasaLocalizationCore(action); - } - - public static IServiceCollection TestAddMasaLocalization( - this IServiceCollection services, - Action? action) - { - MasaApp.SetServiceCollection(services); - return services.AddMasaLocalizationCore(action); - } - - private static IServiceCollection AddMasaLocalizationCore(this IServiceCollection services, - Action? action) - { - services.Configure(options => - { - options.DefaultResourceType ??= typeof(DefaultResource); - }); - services.TryAddSingleton(typeof(IMasaStringLocalizer<>), typeof(MasaStringLocalizer<>)); - services.TryAddSingleton(); - services.TryAddSingleton(); - - action?.Invoke(new Masa.Contrib.Globalization.Localization.LocalizationOptions()); - - var masaLocalizationOptions = services.BuildServiceProvider().GetRequiredService>().Value; - var defaultResourceLocalizer = typeof(IMasaStringLocalizer<>).MakeGenericType(masaLocalizationOptions.DefaultResourceType!); - services.TryAddSingleton(serviceProvider => (IMasaStringLocalizer)serviceProvider.GetRequiredService(defaultResourceLocalizer)); - return services; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs deleted file mode 100644 index 6ddac5c97..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/Internal/Const.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization.Internal; - -internal static class Const -{ - internal const string SUPPORTED_CULTURES_FILE_NAME = "supportedCultures.json"; -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs deleted file mode 100644 index 5fc7ddd80..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.Localization/MasaStringLocalizerOfT.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization; - -public class MasaStringLocalizer : IMasaStringLocalizer -{ - private readonly LocalizationResource? _localizationResource; - public string this[string name] => GetLocalizedString(name); - - public string this[string name, params object[] arguments] - { - get - { - ArgumentNullException.ThrowIfNull(name); - - var value = this[name]; - return string.Format(CultureInfo.CurrentUICulture, value, arguments); - } - } - - public string T(string name) => this[name]; - - public string T(string name, params object[] arguments) => this[name, arguments]; - - public MasaStringLocalizer(IOptions options) - { - _localizationResource = options.Value.Resources.GetOrNull(); - } - - private string GetLocalizedString(string name) - { - var resourceContributor = _localizationResource?.GetResourceContributor(); - if (resourceContributor != null) - { - return resourceContributor.GetOrNull(name) ?? GetLocalizedStringByDefaultCultureName(name); - } - throw new NotImplementedException(); - } - - private string GetLocalizedStringByDefaultCultureName(string name) - { - if (!LocalizationResourceConfiguration.DefaultCultureName.IsNullOrWhiteSpace()) - { - var resourceContributor = - _localizationResource!.GetResourceContributor(new CultureInfo(LocalizationResourceConfiguration.DefaultCultureName)); - return resourceContributor?.GetOrNull(name) ?? name; - } - return name; - } -} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs new file mode 100644 index 000000000..c0f4251ab --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs @@ -0,0 +1,94 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Tests; + +[TestClass] +public class I18NTest +{ + [DataTestMethod] + [DataRow("zh-CN", "吉姆")] + [DataRow("en-US", "Jim")] + public void TestLocalization(string cultureName, string expectedValue) + { + var services = new ServiceCollection(); + services.AddLogging(); + services.TestAddI18N(options => + { + options.UseJson("Resources"); + }); + var serviceProvider = services.BuildServiceProvider(); + var i18N = serviceProvider.GetRequiredService(); + i18N.SetCulture(cultureName); + var value = i18N["Name"]; + Assert.AreEqual(expectedValue, value); + value = i18N.T("Name"); + Assert.AreEqual(expectedValue, value); + value = i18N["Name2"]; + Assert.AreEqual("Name2", value); + } + + [DataTestMethod] + [DataRow("zh-CN", "吉姆")] + [DataRow("en-US", "Jim")] + public void TestLocalization2(string cultureName, string expectedValue) + { + var builder = WebApplication.CreateBuilder(); + builder.Services.TestAddI18N(options => + { + options.UseJson("Resources"); + }); + var serviceProvider = builder.Services.BuildServiceProvider(); + var i18N = serviceProvider.GetRequiredService(); + i18N.SetCulture(cultureName); + var value = i18N["Name"]; + Assert.AreEqual(expectedValue, value); + value = i18N.T("Name"); + Assert.AreEqual(expectedValue, value); + value = i18N["Name2"]; + Assert.AreEqual("Name2", value); + } + + [DataTestMethod] + [DataRow("zh-TW", "Name")] + public void TestLocalization3(string cultureName, string expectedValue) + { + var builder = WebApplication.CreateBuilder(); + builder.Services.AddI18N(options => + { + options.UseJson("Resources"); + }); + var serviceProvider = builder.Services.BuildServiceProvider(); + var i18N = serviceProvider.GetRequiredService(); + i18N.SetCulture(cultureName); + var value = i18N["Name"]; + Assert.AreEqual(expectedValue, value); + value = i18N.T("Name"); + Assert.AreEqual(expectedValue, value); + value = i18N["Name2"]; + Assert.AreEqual("Name2", value); + } + + [DataTestMethod] + [DataRow("zh-TW", "Name")] + public void TestLocalization4(string cultureName, string expectedValue) + { + var builder = WebApplication.CreateBuilder(); + builder.Services.Configure(options => + { + options.Resources + .Add() + .AddJson("/Resources"); + }); + builder.Services.AddI18N(null); + var serviceProvider = builder.Services.BuildServiceProvider(); + var i18N = serviceProvider.GetRequiredService(); + i18N.SetCulture(cultureName); + var value = i18N["Name"]; + Assert.AreEqual(expectedValue, value); + value = i18N.T("Name"); + Assert.AreEqual(expectedValue, value); + value = i18N["Name2"]; + Assert.AreEqual("Name2", value); + } +} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj similarity index 70% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj index 7e1637b97..77e99c80e 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Masa.Contrib.Globalization.Localization.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj @@ -24,21 +24,12 @@ - - + - - - Always - - - - Always - - - + + Always diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/Resources/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs similarity index 74% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs index 3d6675751..c4b2cf9bc 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/_Imports.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs @@ -1,9 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.Contrib.Globalization.Localization.Extensions; +global using Masa.BuildingBlocks.Globalization.I18N; global using Microsoft.AspNetCore.Builder; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Localization; global using Microsoft.VisualStudio.TestTools.UnitTesting; global using System.Globalization; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs deleted file mode 100644 index 37ed98389..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.Localization.Tests/LocalizationResourceTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.Localization.Tests; - -[TestClass] -public class LocalizationResourceTest -{ - [DataTestMethod] - [DataRow("zh-CN", "吉姆")] - [DataRow("en-US", "Jim")] - public void TestLocalization(string cultureName, string expectedValue) - { - var services = new ServiceCollection(); - services.AddLogging(); - services.TestAddMasaLocalization(options => - { - options.UseJson("Resources"); - }); - var serviceProvider = services.BuildServiceProvider(); - CultureInfo.CurrentUICulture = new CultureInfo(cultureName); - var localizer = serviceProvider.GetRequiredService(); - var value = localizer["Name"]; - Assert.AreEqual(expectedValue, value); - value = localizer.T("Name"); - Assert.AreEqual(expectedValue, value); - value = localizer["Name2"]; - Assert.AreEqual("Name2", value); - } - - [DataTestMethod] - [DataRow("zh-CN", "吉姆")] - [DataRow("en-US", "Jim")] - public void TestLocalization2(string cultureName, string expectedValue) - { - var builder = WebApplication.CreateBuilder(); - builder.Services.TestAddMasaLocalization(options => - { - options.UseJson("Resources"); - }); - var serviceProvider = builder.Services.BuildServiceProvider(); - CultureInfo.CurrentUICulture = new CultureInfo(cultureName); - var localizer = serviceProvider.GetRequiredService(); - var value = localizer["Name"]; - Assert.AreEqual(expectedValue, value); - value = localizer.T("Name"); - Assert.AreEqual(expectedValue, value); - value = localizer["Name2"]; - Assert.AreEqual("Name2", value); - } - - [DataTestMethod] - [DataRow("zh-CN", "吉姆")] - [DataRow("en-US", "Jim")] - public void TestLocalizationByMasaConfigurationLocal(string cultureName, string expectedValue) - { - var builder = WebApplication.CreateBuilder(); - builder.Services.AddMasaConfiguration(); - builder.Services.TestAddMasaLocalization(options => - { - options.UseJson("Resources"); - }); - var serviceProvider = builder.Services.BuildServiceProvider(); - CultureInfo.CurrentUICulture = new CultureInfo(cultureName); - var localizer = serviceProvider.GetRequiredService(); - var value = localizer["Name"]; - Assert.AreEqual(expectedValue, value); - value = localizer.T("Name"); - Assert.AreEqual(expectedValue, value); - value = localizer["Name2"]; - Assert.AreEqual("Name2", value); - } -} From 30e70d2596b310fb091bed0743a0a4190c0790c2 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 19 Oct 2022 23:51:14 +0800 Subject: [PATCH 09/38] feat: Support I18N --- .../DefaultLanguageProvider.cs | 10 +- .../DefaultResource.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 15 +-- .../I18NOfT.cs | 64 ++++++++++++ .../I18NResourceDictionary.cs | 3 - .../I18NResourceResourceConfiguration.cs | 4 +- .../II18N.cs | 53 +++++++++- .../Options}/I18NOptions.cs | 2 +- .../Options/MasaI18NOptions.cs | 5 - .../_Imports.cs | 4 + .../Extensions/I18NOptionsExtensions.cs | 53 +++++----- .../Internal/Const.cs | 2 + .../Extensions/I18NOptionsExtensions.cs | 40 +++++--- .../Extensions/I18NResourceExtensions.cs | 4 +- .../I18NOfT.cs | 55 ----------- .../Internal/Const.cs | 2 +- .../Masa.Contrib.Globalization.I18N/README.md | 98 +++++++++++++++++++ .../README.zh-CN.md | 98 +++++++++++++++++++ .../_Imports.cs | 4 +- .../I18NTest.cs | 39 +++++++- ...sa.Contrib.Globalization.I18N.Tests.csproj | 8 +- .../Resources/{ => i18n}/en-US.json | 0 .../{ => i18n}/supportedCultures.json | 0 .../Resources/{ => i18n}/zh-CN.json | 0 24 files changed, 429 insertions(+), 136 deletions(-) rename src/{Contrib/Globalization/Masa.Contrib.Globalization.I18N => BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N}/DefaultResource.cs (78%) rename src/{Contrib/Globalization/Masa.Contrib.Globalization.I18N => BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N}/Extensions/ServiceCollectionExtensions.cs (73%) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs rename src/{Contrib/Globalization/Masa.Contrib.Globalization.I18N => BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options}/I18NOptions.cs (75%) delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{ => i18n}/en-US.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{ => i18n}/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{ => i18n}/zh-CN.json (100%) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs index b1d0bb9cd..311c856d9 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs @@ -5,13 +5,5 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public class DefaultLanguageProvider : ILanguageProvider { - private readonly IOptionsMonitor _options; - - public DefaultLanguageProvider(IOptionsMonitor options) - { - _options = options; - } - - public IReadOnlyList GetLanguages() - => _options.CurrentValue.Languages; + public IReadOnlyList GetLanguages() => I18NResourceResourceConfiguration.Languages.ToArray(); } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/DefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultResource.cs similarity index 78% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/DefaultResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultResource.cs index 23bed80da..06523b878 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/DefaultResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultResource.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18N; public class DefaultResource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs similarity index 73% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index e9c7aac62..bd8bc7090 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -27,18 +27,19 @@ private static IServiceCollection AddI18NCore( this IServiceCollection services, Action? action) { - services.Configure(options => - { - options.DefaultResourceType ??= typeof(DefaultResource); - }); services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); services.TryAddSingleton(); action?.Invoke(new I18NOptions()); - var masaLocalizationOptions = services.BuildServiceProvider().GetRequiredService>().Value; - var defaultResourceLocalizer = typeof(II18N<>).MakeGenericType(masaLocalizationOptions.DefaultResourceType!); - services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService(defaultResourceLocalizer)); + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); + + var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); + foreach (var resource in i18NOptions.Value.Resources) + { + I18NResourceResourceConfiguration.Resources[resource.Key] = resource.Value; + } + return services; } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs new file mode 100644 index 000000000..a989f1c04 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs @@ -0,0 +1,64 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +public class I18N : II18N +{ + private readonly I18NResource? _resource; + + public string this[string name] => T(name); + + public string? this[string name, bool returnKey] => T(name, returnKey); + + public string this[string name, params object[] arguments] => T(name, arguments); + + public string? this[string name, bool returnKey, params object[] arguments] => T(name, returnKey, arguments); + + public I18N() + { + _resource = I18NResourceResourceConfiguration.Resources.GetOrNull(); + } + + public string T(string name) + => T(name, true)!; + + /// + /// Gets the string resource with the given name. + /// + /// The name of the string resource. + /// Return Key when key does not exist, default: true + /// + public string? T(string name, bool returnKey) + { + var resourceContributor = _resource?.GetResourceContributor(CultureInfo.CurrentUICulture); + if (resourceContributor != null) + { + return resourceContributor.GetOrNull(name) ?? (returnKey ? name : null); + } + + return returnKey ? name : null; + } + + public string T(string name, params object[] arguments) + => T(name, true, arguments)!; + + public string? T(string name, bool returnKey, params object[] arguments) + { + ArgumentNullException.ThrowIfNull(name); + + var value = this.T(name, returnKey); + if (value != null) + return string.Format(CultureInfo.CurrentUICulture, value, arguments); + + return null; + } + + public void SetCulture(string cultureName, bool useUserOverride = true) + => SetCulture(new CultureInfo(cultureName, useUserOverride)); + + public virtual void SetCulture(CultureInfo culture) + { + CultureInfo.CurrentUICulture = culture; + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs index 28b589080..39cdfb1a4 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs @@ -13,9 +13,6 @@ public I18NResource Add() public I18NResource Add(Type resourceType) { - if (ContainsKey(resourceType)) - throw new ArgumentException("This resource is already added before: " + resourceType.FullName); - return this[resourceType] = new I18NResource(resourceType); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs index b4cdd8de4..c8b8d3b89 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs @@ -7,5 +7,7 @@ public static class I18NResourceResourceConfiguration { public static readonly string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; - public static string DefaultCultureName { get; set; } + public static I18NResourceDictionary Resources { get; set; } = new(); + + public static IEnumerable Languages { get; set; } = new List(); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs index 549eb6cda..a643f1bae 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs @@ -5,24 +5,71 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public interface II18N { - /// Gets the string resource with the given name. + /// + /// Gets the string resource with the given name. + /// /// The name of the string resource. - /// The string resource as a . + /// string this[string name] { get; } + /// + /// Gets the string resource with the given name. + /// + /// The name of the string resource. + /// Return Key when key does not exist, default: true + /// + string? this[string name, bool returnKey] { get; } + /// /// Gets the string resource with the given name and formatted with the supplied arguments. /// /// The name of the string resource. /// The values to format the string with. - /// The formatted string resource as a . + /// string this[string name, params object[] arguments] { get; } + string? this[string name, bool returnKey, params object[] arguments] => T(name, returnKey, arguments); + + /// + /// Gets the string resource with the given name. + /// + /// The name of the string resource. + /// string T(string name); + /// + /// Gets the string resource with the given name. + /// + /// The name of the string resource. + /// Return Key when key does not exist, default: true + /// + string? T(string name, bool returnKey); + + /// + /// Gets the string resource with the given name and formatted with the supplied arguments. + /// + /// The name of the string resource. + /// The values to format the string with. string T(string name, params object[] arguments); + /// + /// Gets the string resource with the given name and formatted with the supplied arguments. + /// + /// The name of the string resource. + /// Return Key when key does not exist, default: true + /// The values to format the string with. + string? T(string name, bool returnKey, params object[] arguments); + + /// + /// Set the CultureName for the current request + /// + /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. + /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). void SetCulture(string cultureName, bool useUserOverride = true); + /// + /// Set the CultureName for the current request + /// + /// void SetCulture(CultureInfo culture); } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs similarity index 75% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs index 22be9b825..5d027e341 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18N.Options; public class I18NOptions { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs index 3cbcc94e6..e91af76c1 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs @@ -6,15 +6,10 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public class MasaI18NOptions { - public Type? DefaultResourceType { get; set; } - - public List Languages { get; set; } - public I18NResourceDictionary Resources { get; } public MasaI18NOptions() { Resources = new(); - Languages = new(); } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index b51383891..71ab2adf7 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -1,5 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Globalization.I18N.Options; +global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.Extensions.Options; global using System.Globalization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index 560a4c5b1..982ad4fe8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -3,47 +3,52 @@ // ReSharper disable once CheckNamespace +using Masa.BuildingBlocks.Globalization.I18N.Options; + namespace Masa.Contrib.Globalization.I18N; public static class I18NOptionsExtensions { - public static I18NOptions UseDcc( + public static void UseDcc( this I18NOptions localization, params LanguageInfo[] languages) - => localization.UseDcc(DccConfig.AppId, "I18n", languages); + => localization.UseDcc(Dcc.Internal.Const.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Const.SUPPORTED_CULTURES_NAME, languages); - public static I18NOptions UseDcc( + public static void UseDcc( this I18NOptions localization, string configObject, + string supportCultureName, params LanguageInfo[] languages) - => localization.UseDcc(DccConfig.AppId, configObject, languages); + => localization.UseDcc(DccConfig.AppId, configObject, supportCultureName, languages); - public static I18NOptions UseDcc( + public static void UseDcc( this I18NOptions localization, string appId, string configObject, + string supportCultureName, params LanguageInfo[] languages) { var services = MasaApp.GetServices(); - services.Configure(options => + if (languages.Length == 0) { - if (languages.Length == 0) - { - var serviceProvider = services.BuildServiceProvider(); - var configurationApiClient = serviceProvider.GetRequiredService(); - languages = configurationApiClient.GetAsync>( - $"{configObject}.{Dcc.Internal.Const.SUPPORTED_CULTURES_NAME}", - newLanguages - => - { - options.Languages = newLanguages.ToList(); - }).ConfigureAwait(false).GetAwaiter().GetResult().ToArray(); - } - options.Languages = languages.ToList(); - options.Resources - .Add() - .UseDcc(appId, configObject, languages); - }); - return localization; + var serviceProvider = services.BuildServiceProvider(); + var configurationApiClient = serviceProvider.GetRequiredService(); + languages = configurationApiClient.GetAsync>( + $"{configObject}.{supportCultureName}", + newLanguages + => + { + I18NResourceResourceConfiguration.Languages = newLanguages; + I18NResourceResourceConfiguration + .Resources + .Add() + .UseDcc(appId, configObject, newLanguages.ToArray()); + }).ConfigureAwait(false).GetAwaiter().GetResult().ToArray(); + } + I18NResourceResourceConfiguration.Languages = languages.ToList(); + I18NResourceResourceConfiguration + .Resources + .Add() + .UseDcc(appId, configObject, languages); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs index b952c6e0b..0b523c2da 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs @@ -5,5 +5,7 @@ namespace Masa.Contrib.Globalization.I18N.Dcc.Internal; internal static class Const { + internal const string DEFAULT_CONFIG_OBJECT_NAME = "i18n"; + internal const string SUPPORTED_CULTURES_NAME = "supportedCultures"; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs index 325093636..f9b7098ef 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -using Microsoft.Extensions.FileProviders; +using Masa.BuildingBlocks.Globalization.I18N.Options; namespace Masa.Contrib.Globalization.I18N; @@ -23,8 +23,6 @@ public static void UseJson(this I18NOptions _, string supportCultureName, params LanguageInfo[] languages) { - var services = MasaApp.GetServices(); - languageDirectory = PathHelper.GetAndCheckLanguageDirectory(languageDirectory); if (languages.Length == 0) @@ -32,26 +30,40 @@ public static void UseJson(this I18NOptions _, languages = GetLanguageInfos(languageDirectory, supportCultureName).ToArray(); MonitorChange(languageDirectory, supportCultureName, () => { - var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); - var options = serviceProvider.GetRequiredService>(); - options.Value.Languages = GetLanguageInfos(languageDirectory, supportCultureName).ToList(); + I18NResourceResourceConfiguration.Languages = GetLanguageInfos(languageDirectory, supportCultureName).ToList(); + I18NResourceResourceConfiguration + .Resources + .Add() + .AddJson(languageDirectory, I18NResourceResourceConfiguration.Languages.ToArray()); }); } - services.Configure(options => - { - options.Languages = languages.ToList(); - - options.Resources - .Add() - .AddJson(languageDirectory, languages); - }); + I18NResourceResourceConfiguration.Languages = languages.ToList(); + I18NResourceResourceConfiguration + .Resources + .Add() + .AddJson(languageDirectory, languages); } private static List GetLanguageInfos( string languageDirectory, string supportCultureName) { + start: + try + { + using var fileStream = new FileStream(Path.Combine(languageDirectory, supportCultureName),FileMode.Open); + if (!fileStream.CanRead) + { + Task.Delay(300); + goto start; + } + } + catch (IOException) + { + Task.Delay(300); + goto start; + } var supportCultureFilePath = Path.Combine(languageDirectory, supportCultureName); var content = File.ReadAllText(supportCultureFilePath); return System.Text.Json.JsonSerializer.Deserialize>(content)!; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index 339323ed9..e8f05c565 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -11,7 +11,7 @@ public static class I18NResourceExtensions private static IMasaConfiguration? _masaConfiguration; - public static I18NResource AddJson( + public static void AddJson( this I18NResource resource, string languageDirectory, params LanguageInfo[] languages) @@ -25,8 +25,6 @@ public static I18NResource AddJson( { resource.AddContributor(resourceContributor.CultureName, resourceContributor); } - - return resource; } private static List GetResourceContributors( diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs deleted file mode 100644 index 8405d3484..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/I18NOfT.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N; - -public class I18N : II18N -{ - private readonly I18NResource? _resource; - public string this[string name] => T(name); - - public string this[string name, params object[] arguments] => T(name, arguments); - - public I18N(IOptions options) - { - _resource = options.Value.Resources.GetOrNull(); - } - - public string T(string name) - { - var resourceContributor = _resource?.GetResourceContributor(CultureInfo.CurrentUICulture); - if (resourceContributor != null) - { - return resourceContributor.GetOrNull(name) ?? GetLocalizedStringByDefaultCultureName(name); - } - - return name; - } - - public string T(string name, params object[] arguments) - { - ArgumentNullException.ThrowIfNull(name); - - var value = this[name]; - return string.Format(CultureInfo.CurrentUICulture, value, arguments); - } - - public void SetCulture(string cultureName, bool useUserOverride = true) - => SetCulture(new CultureInfo(cultureName, useUserOverride)); - - public virtual void SetCulture(CultureInfo culture) - { - CultureInfo.DefaultThreadCurrentUICulture = culture; - } - - private string GetLocalizedStringByDefaultCultureName(string name) - { - if (!I18NResourceResourceConfiguration.DefaultCultureName.IsNullOrWhiteSpace()) - { - var resourceContributor = - _resource!.GetResourceContributor(new CultureInfo(I18NResourceResourceConfiguration.DefaultCultureName)); - return resourceContributor?.GetOrNull(name) ?? name; - } - return name; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs index 9e906b1fd..f08443f8a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs @@ -7,5 +7,5 @@ internal static class Const { internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; - internal const string DEFAULT_RESOURCE_PATH = "Resources"; + internal const string DEFAULT_RESOURCE_PATH = "Resources/i18n"; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md new file mode 100644 index 000000000..a3c9e41d8 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md @@ -0,0 +1,98 @@ +[中](README.zh-CN.md) | EN + +Provide [Internationalization](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization) capability + +## Masa.Contrib.Globalization.I18N + +Example: + +``` powershell +Install-Package Masa.Contrib.Globalization.I18N +``` + +### getting Started + +1. Default resource folder structure + +``` structure +- Resources + - i18n + - en-US.json + - zh-CN.json + - supportedCultures.json +``` + +* en-US.json + +``` en-US.json +{ + "Home":"Home", + "Docs":"Docs", + "Blog":"Blog", + "Team":"Team", + "Search":"Search" + "User":{ + "Name":"Name" + } +} +``` + +* zh-CN.json + +``` zh-CN.json +{ + "Home":"Home", + "Docs":"Documents", + "Blog":"Blog", + "Team":"Team", + "Search":"Search", + "User":{ + "Name":"Name" + } +} +``` + +* supportedCultures.json + +``` supportedCultures.json +[ + { + "DefaultCulture": true, + "Culture":"zh-CN", + "Display":"Simplified Chinese", + "Icon": "{Replace-Your-Icon}" + }, + { + "DefaultCulture": false, + "Culture":"en-US", + "Display":"English (United States)", + "Icon": "{Replace-Your-Icon}" + } +] +``` + +2. Register to use I18N, modify `Program.cs` + +``` C# +services.AddI18N(options => +{ + options.UseJson();//Use the i18n resource file in the local `Resources/i18n` folder +}); +``` + +3. How to use I18N + +``` C# +II18N i18n;//Get from DI +i18n.SetCulture("zh-CN");//Switch the language to zh-CN +var home = i18n.T("Home");//Get the value of the language corresponding to the key value Home, this method call will return "Home"; + +var name = i18n.T("User.Name");//Output: name (support nesting) +``` + +4. Get all languages + +``` C# +ILanguageProvider languageProvider;//Get from DI +var languages = languageProvider.GetLanguages(); +``` \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md new file mode 100644 index 000000000..d7469112f --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md @@ -0,0 +1,98 @@ +中 | [EN](README.md) + +提供[国际化](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization)能力 + +## Masa.Contrib.Globalization.I18N + +用例: + +``` powershell +Install-Package Masa.Contrib.Globalization.I18N +``` + +### 入门 + +1. 默认资源文件夹结构 + +``` structure +- Resources + - i18n + - en-US.json + - zh-CN.json + - supportedCultures.json +``` + +* en-US.json + +``` en-US.json +{ + "Home":"Home", + "Docs":"Docs", + "Blog":"Blog", + "Team":"Team", + "Search":"Search" + "User":{ + "Name":"Name" + } +} +``` + +* zh-CN.json + +``` zh-CN.json +{ + "Home":"首页", + "Docs":"文档", + "Blog":"博客", + "Team":"团队", + "Search":"搜索", + "User":{ + "Name":"名称" + } +} +``` + +* supportedCultures.json + +``` supportedCultures.json +[ + { + "DefaultCulture": true, + "Culture":"zh-CN", + "Display":"中文简体", + "Icon": "{Replace-Your-Icon}" + }, + { + "DefaultCulture": false, + "Culture":"en-US", + "Display":"English (United States)", + "Icon": "{Replace-Your-Icon}" + } +] +``` + +2. 注册使用I18N, 修改`Program.cs` + +``` C# +services.AddI18N(options => +{ + options.UseJson();//使用本地`Resources/i18n`文件夹下的i18n资源文件 +}); +``` + +3. 如何使用I18N + +``` C# +II18N i18n;//从DI获取 +i18n.SetCulture("zh-CN");//将语言切换成zh-CN +var home = i18n.T("Home");//获取键值Home对应语言的值,此方法调用将返回"首页"; + +var name = i18n.T("User.Name");//输出:名称(支持嵌套) +``` + +4. 获取所有语言 + +``` C# +ILanguageProvider languageProvider;//从DI获取 +var languages = languageProvider.GetLanguages(); +``` \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index baf0f7ab7..088934745 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -8,8 +8,6 @@ global using Masa.Contrib.Globalization.I18N.Json; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.DependencyInjection.Extensions; +global using Microsoft.Extensions.FileProviders; global using Microsoft.Extensions.Localization; -global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; -global using System.Globalization; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs index c0f4251ab..13800d4a3 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs @@ -6,6 +6,15 @@ namespace Masa.Contrib.Globalization.I18N.Tests; [TestClass] public class I18NTest { + private const string DEFAULT_RESOURCE = "Resources/i18n"; + + [TestInitialize] + public void Initialize() + { + I18NResourceResourceConfiguration.Languages = new List(); + I18NResourceResourceConfiguration.Resources = new(); + } + [DataTestMethod] [DataRow("zh-CN", "吉姆")] [DataRow("en-US", "Jim")] @@ -15,7 +24,7 @@ public void TestLocalization(string cultureName, string expectedValue) services.AddLogging(); services.TestAddI18N(options => { - options.UseJson("Resources"); + options.UseJson(); }); var serviceProvider = services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); @@ -36,7 +45,7 @@ public void TestLocalization2(string cultureName, string expectedValue) var builder = WebApplication.CreateBuilder(); builder.Services.TestAddI18N(options => { - options.UseJson("Resources"); + options.UseJson(DEFAULT_RESOURCE); }); var serviceProvider = builder.Services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); @@ -56,7 +65,7 @@ public void TestLocalization3(string cultureName, string expectedValue) var builder = WebApplication.CreateBuilder(); builder.Services.AddI18N(options => { - options.UseJson("Resources"); + options.UseJson(DEFAULT_RESOURCE); }); var serviceProvider = builder.Services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); @@ -78,7 +87,7 @@ public void TestLocalization4(string cultureName, string expectedValue) { options.Resources .Add() - .AddJson("/Resources"); + .AddJson("/i18n"); }); builder.Services.AddI18N(null); var serviceProvider = builder.Services.BuildServiceProvider(); @@ -91,4 +100,26 @@ public void TestLocalization4(string cultureName, string expectedValue) value = i18N["Name2"]; Assert.AreEqual("Name2", value); } + + + [DataTestMethod] + [DataRow("zh-CN", "吉姆")] + [DataRow("en-US", "Jim")] + public void TestLocalization5(string cultureName, string expectedValue) + { + var builder = WebApplication.CreateBuilder(); + builder.Services.TestAddI18N(options => + { + options.UseJson(DEFAULT_RESOURCE, new LanguageInfo("zh-CN"), new LanguageInfo("en-US")); + }); + var serviceProvider = builder.Services.BuildServiceProvider(); + var i18N = serviceProvider.GetRequiredService(); + i18N.SetCulture(cultureName); + var value = i18N["Name"]; + Assert.AreEqual(expectedValue, value); + value = i18N.T("Name"); + Assert.AreEqual(expectedValue, value); + value = i18N["Name2"]; + Assert.AreEqual("Name2", value); + } } diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj index 77e99c80e..a916c4caf 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj @@ -28,10 +28,14 @@ - - + + Always + + + + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/zh-CN.json From 1dd1f429ede1a0e3390b79d2f1c8fd7d1f41f224 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 31 Oct 2022 18:32:33 +0800 Subject: [PATCH 10/38] =?UTF-8?q?feat:=20Add=EF=BC=A9I18N?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Masa.Framework.sln | 22 +++++ .../Extensions/ServiceCollectionExtensions.cs | 45 --------- .../I18NOfT.cs | 16 +-- .../Options/I18NOptions.cs | 8 -- .../_Imports.cs | 5 - .../I18NOfT.cs | 43 ++++++++ ...a.Contrib.Globalization.I18N.Blazor.csproj | 17 ++++ .../ServiceCollectionExtensions.cs | 40 ++++++++ .../_Imports.cs | 10 ++ .../Extensions/I18NOptionsExtensions.cs | 12 +-- .../Extensions/I18NResourceExtensions.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 97 +++++++++++++++++++ ...ovider.cs => FileConfigurationProvider.cs} | 4 +- ...ovider.cs => JsonConfigurationProvider.cs} | 4 +- ...onSource.cs => JsonConfigurationSource.cs} | 6 +- .../JsonConfigurationUtils.cs} | 24 +---- .../Options/I18NOptions.cs | 16 +++ .../_Imports.cs | 2 + ...rib.Globalization.I18N.Blazor.Tests.csproj | 41 ++++++++ .../Resources/i18n/en-US.json | 6 ++ .../Resources/i18n/supportedCultures.json | 10 ++ .../Resources/i18n/zh-CN.json | 6 ++ .../ServicesCollectionsTest.cs | 19 ++++ .../_Imports.cs | 6 ++ .../I18NTest.cs | 60 +----------- .../ApplicationBuilderExtensions.cs | 1 + .../Extensions/MvcBuilderExtensions.cs | 10 +- .../Handlers/ExceptionHandlerMiddleware.cs | 4 +- .../Handlers/ExceptionHandlingMiddleware.cs | 2 + .../Handlers/GlobalExceptionFilter.cs | 2 + .../IMasaExceptionHandler.cs | 2 + .../Internal/ExceptionExtensions.cs | 2 + .../Internal/ExceptionHandlerExtensions.cs | 4 +- .../Masa.Utils.Exceptions/MasaException.cs | 2 + .../Options/MasaExceptionHandlerOptions.cs | 2 + .../Options/MasaExceptionHandlingOptions.cs | 2 + .../MasaExceptionLogRelationOptions.cs | 2 + .../Results/DefaultExceptionResult.cs | 2 + .../InternalServerErrorObjectResult.cs | 2 + .../Results/UserFriendlyExceptionResult.cs | 2 + 40 files changed, 402 insertions(+), 160 deletions(-) delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/{FileLocalizationConfigurationProvider.cs => FileConfigurationProvider.cs} (93%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/{JsonLocalizationConfigurationProvider.cs => JsonConfigurationProvider.cs} (72%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/{JsonLocalizationConfigurationSource.cs => JsonConfigurationSource.cs} (81%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/{Extensions/I18NOptionsExtensions.cs => Json/JsonConfigurationUtils.cs} (72%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 4182d50db..f5e82e424 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -589,6 +589,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Dcc\Masa.Contrib.Globalization.I18N.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Blazor", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Blazor\Masa.Contrib.Globalization.I18N.Blazor.csproj", "{C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Blazor.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Blazor.Tests\Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj", "{EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2085,6 +2089,22 @@ Global {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|Any CPU.Build.0 = Release|Any CPU {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.ActiveCfg = Release|Any CPU {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.Build.0 = Release|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|x64.ActiveCfg = Debug|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|x64.Build.0 = Debug|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|Any CPU.Build.0 = Release|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|x64.ActiveCfg = Release|Any CPU + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|x64.Build.0 = Release|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|x64.ActiveCfg = Debug|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|x64.Build.0 = Debug|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|Any CPU.Build.0 = Release|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|x64.ActiveCfg = Release|Any CPU + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2375,6 +2395,8 @@ Global {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} {6C732EBE-22CC-4160-B427-F4558C899024} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} {B0EFDF9E-81FF-4880-992B-8A65A2008717} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs deleted file mode 100644 index bd8bc7090..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Microsoft.Extensions.DependencyInjection; - -public static class ServiceCollectionExtensions -{ - public static IServiceCollection AddI18N( - this IServiceCollection services, - Action? action) - { - MasaApp.TrySetServiceCollection(services); - return services.AddI18NCore(action); - } - - public static IServiceCollection TestAddI18N( - this IServiceCollection services, - Action? action) - { - MasaApp.SetServiceCollection(services); - return services.AddI18NCore(action); - } - - private static IServiceCollection AddI18NCore( - this IServiceCollection services, - Action? action) - { - services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); - services.TryAddSingleton(); - - action?.Invoke(new I18NOptions()); - - services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); - - var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); - foreach (var resource in i18NOptions.Value.Resources) - { - I18NResourceResourceConfiguration.Resources[resource.Key] = resource.Value; - } - - return services; - } -} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs index a989f1c04..e7dd69a1b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs @@ -20,7 +20,7 @@ public I18N() _resource = I18NResourceResourceConfiguration.Resources.GetOrNull(); } - public string T(string name) + public virtual string T(string name) => T(name, true)!; /// @@ -29,9 +29,9 @@ public string T(string name) /// The name of the string resource. /// Return Key when key does not exist, default: true /// - public string? T(string name, bool returnKey) + public virtual string? T(string name, bool returnKey) { - var resourceContributor = _resource?.GetResourceContributor(CultureInfo.CurrentUICulture); + var resourceContributor = _resource?.GetResourceContributor(GetCultureInfo()); if (resourceContributor != null) { return resourceContributor.GetOrNull(name) ?? (returnKey ? name : null); @@ -40,21 +40,23 @@ public string T(string name) return returnKey ? name : null; } - public string T(string name, params object[] arguments) + public virtual string T(string name, params object[] arguments) => T(name, true, arguments)!; - public string? T(string name, bool returnKey, params object[] arguments) + public virtual string? T(string name, bool returnKey, params object[] arguments) { ArgumentNullException.ThrowIfNull(name); var value = this.T(name, returnKey); if (value != null) - return string.Format(CultureInfo.CurrentUICulture, value, arguments); + return string.Format(GetCultureInfo(), value, arguments); return null; } - public void SetCulture(string cultureName, bool useUserOverride = true) + public virtual CultureInfo GetCultureInfo() => CultureInfo.CurrentUICulture; + + public virtual void SetCulture(string cultureName, bool useUserOverride = true) => SetCulture(new CultureInfo(cultureName, useUserOverride)); public virtual void SetCulture(CultureInfo culture) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs deleted file mode 100644 index 5d027e341..000000000 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.BuildingBlocks.Globalization.I18N.Options; - -public class I18NOptions -{ -} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index 71ab2adf7..38d9e107b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -1,9 +1,4 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Globalization.I18N; -global using Masa.BuildingBlocks.Globalization.I18N.Options; -global using Microsoft.Extensions.DependencyInjection.Extensions; -global using Microsoft.Extensions.Options; global using System.Globalization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs new file mode 100644 index 000000000..a05a0eaae --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs @@ -0,0 +1,43 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Blazor; + +[ExcludeFromCodeCoverage] +public class I18N : Masa.BuildingBlocks.Globalization.I18N.I18N +{ + private const string CultureCookieKey = "Masa_I18nConfig_Culture"; + private readonly IJSRuntime _jsRuntime; + + public I18N(IJSRuntime jsRuntime) => _jsRuntime = jsRuntime; + + const string GetCookieJs = + "(function(name){const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);const arr = document.cookie.match(reg);if (arr) {return unescape(arr[2]);}return null;})"; + + const string SetCookieJs = + "(function(name,value){ var Days = 30;var exp = new Date();exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);document.cookie = `${name}=${escape(value.toString())};path=/;expires=${exp.toUTCString()}`;})"; + + public override CultureInfo GetCultureInfo() + { + if (_jsRuntime is IJSInProcessRuntime jsInProcess) + { + var cultureName = jsInProcess.Invoke("eval", $"{GetCookieJs}('{CultureCookieKey}')"); + return new CultureInfo(cultureName); + } + return CultureInfo.CurrentUICulture; + } + + public override void SetCulture(CultureInfo culture) + { + try + { + _jsRuntime.InvokeVoidAsync("eval", $"{SetCookieJs}('{CultureCookieKey}','{culture.Name}')") + .ConfigureAwait(false) + .GetAwaiter() + .GetResult(); + } + catch (Exception ex) + { + } + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj new file mode 100644 index 000000000..89999cfb6 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..70fa496cd --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs @@ -0,0 +1,40 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.Extensions.DependencyInjection; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddI18NForBlazor(this IServiceCollection services, + Action? action = null, + params LanguageInfo[] languages) + { + services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); + services.AddI18N(action, languages); + return services; + } + + public static IServiceCollection AddI18NForBlazor( + this IServiceCollection services, + string languageDirectory, + Action? action = null, + params LanguageInfo[] languages) + { + services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); + return services.AddI18N(languageDirectory, action, languages); + } + + public static IServiceCollection AddI18NForBlazor( + this IServiceCollection services, + string languageDirectory, + string supportCultureName, + Action? action = null, + params LanguageInfo[] languages) + { + services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); + services.AddI18N(languageDirectory, supportCultureName, action, languages); + return services; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs new file mode 100644 index 000000000..a0cb24e93 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs @@ -0,0 +1,10 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.Contrib.Globalization.I18N; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.DependencyInjection.Extensions; +global using Microsoft.JSInterop; +global using System.Diagnostics.CodeAnalysis; +global using System.Globalization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index 982ad4fe8..a0dd7f5db 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -3,26 +3,24 @@ // ReSharper disable once CheckNamespace -using Masa.BuildingBlocks.Globalization.I18N.Options; - namespace Masa.Contrib.Globalization.I18N; public static class I18NOptionsExtensions { public static void UseDcc( - this I18NOptions localization, + this I18NOptions i18NOptions, params LanguageInfo[] languages) - => localization.UseDcc(Dcc.Internal.Const.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Const.SUPPORTED_CULTURES_NAME, languages); + => i18NOptions.UseDcc(Dcc.Internal.Const.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Const.SUPPORTED_CULTURES_NAME, languages); public static void UseDcc( - this I18NOptions localization, + this I18NOptions i18NOptions, string configObject, string supportCultureName, params LanguageInfo[] languages) - => localization.UseDcc(DccConfig.AppId, configObject, supportCultureName, languages); + => i18NOptions.UseDcc(DccConfig.AppId, configObject, supportCultureName, languages); public static void UseDcc( - this I18NOptions localization, + this I18NOptions i18NOptions, string appId, string configObject, string supportCultureName, diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index e8f05c565..e4fce18cd 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -81,7 +81,7 @@ private static IConfiguration AddJsonConfigurationSource( } var configurationBuilder = new ConfigurationBuilder(); var jsonLocalizationConfigurationSource = - new JsonLocalizationConfigurationSource(resourceType, languageDirectory, languages.Select(l => l.Culture), + new JsonConfigurationSource(resourceType, languageDirectory, languages.Select(l => l.Culture), useMasaConfiguration); configurationBuilder.Add(jsonLocalizationConfigurationSource); var localizationConfiguration = configurationBuilder.Build(); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..1f3fea4e9 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,97 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.Extensions.DependencyInjection; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddI18N( + this IServiceCollection services, + Action? action = null, + params LanguageInfo[] languages) + => services.AddI18N( + Masa.Contrib.Globalization.I18N.Internal.Const.DEFAULT_RESOURCE_PATH, + Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + action, + languages); + + public static IServiceCollection AddI18N( + this IServiceCollection services, + string languageDirectory, + Action? action = null, + params LanguageInfo[] languages) + => services.AddI18N( + languageDirectory, + Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + action, + languages); + + public static IServiceCollection AddI18N( + this IServiceCollection services, + string languageDirectory, + string supportCultureName, + Action? action = null, + params LanguageInfo[] languages) + { + MasaApp.TrySetServiceCollection(services); + return services.AddI18NCore(languageDirectory, supportCultureName, languages); + } + + public static IServiceCollection TestAddI18N( + this IServiceCollection services, + Action? action = null, + params LanguageInfo[] languages) + => services.TestAddI18N( + Masa.Contrib.Globalization.I18N.Internal.Const.DEFAULT_RESOURCE_PATH, + Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + action, + languages); + + public static IServiceCollection TestAddI18N( + this IServiceCollection services, + string languageDirectory, + Action? action = null, + params LanguageInfo[] languages) + => services.TestAddI18N( + languageDirectory, + Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + action, + languages); + + public static IServiceCollection TestAddI18N( + this IServiceCollection services, + string languageDirectory, + string supportCultureName, + Action? action = null, + params LanguageInfo[] languages) + { + MasaApp.SetServiceCollection(services); + services.AddI18NCore(languageDirectory, supportCultureName, languages); + I18NOptions i18NOptions = new I18NOptions(services); + action?.Invoke(i18NOptions); + return services; + } + + private static IServiceCollection AddI18NCore( + this IServiceCollection services, + string languageDirectory, + string supportCultureName, + params LanguageInfo[] languages) + { + services.AddOptions(); + services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); + services.TryAddSingleton(); + + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); + + var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); + foreach (var resource in i18NOptions.Value.Resources) + { + I18NResourceResourceConfiguration.Resources[resource.Key] = resource.Value; + } + JsonConfigurationUtils.AddJson(languageDirectory, supportCultureName, languages); + return services; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs similarity index 93% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileLocalizationConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs index 95af8bda9..03695bf0e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileLocalizationConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Globalization.I18N; -public abstract class FileLocalizationConfigurationProvider : ConfigurationProvider +public abstract class FileConfigurationProvider : ConfigurationProvider { private readonly string _resourceType; private readonly string _languageDirectory; @@ -11,7 +11,7 @@ public abstract class FileLocalizationConfigurationProvider : ConfigurationProvi private readonly bool _useMasaConfiguration; private readonly Dictionary> _dictionary; - protected FileLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) + protected FileConfigurationProvider(JsonConfigurationSource configurationSource) { _resourceType = configurationSource.ResourceType.Name; _languageDirectory = configurationSource.LanguageDirectory; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs similarity index 72% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs index a83c52174..8dee9e6bc 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs @@ -3,9 +3,9 @@ namespace Masa.Contrib.Globalization.I18N.Json; -public class JsonLocalizationConfigurationProvider : FileLocalizationConfigurationProvider +public class JsonConfigurationProvider : FileConfigurationProvider { - public JsonLocalizationConfigurationProvider(JsonLocalizationConfigurationSource configurationSource) + public JsonConfigurationProvider(JsonConfigurationSource configurationSource) : base(configurationSource) { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs similarity index 81% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationSource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs index 1120707f0..2a941b8c0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonLocalizationConfigurationSource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Globalization.I18N.Json; -public class JsonLocalizationConfigurationSource : IConfigurationSource +public class JsonConfigurationSource : IConfigurationSource { public Type ResourceType { get; } @@ -13,7 +13,7 @@ public class JsonLocalizationConfigurationSource : IConfigurationSource public bool UseMasaConfiguration { get; } - public JsonLocalizationConfigurationSource( + public JsonConfigurationSource( Type resourceType, string languageDirectory, IEnumerable cultureNames, @@ -27,7 +27,7 @@ public JsonLocalizationConfigurationSource( public IConfigurationProvider Build(IConfigurationBuilder builder) { - var configurationProvider = new JsonLocalizationConfigurationProvider(this); + var configurationProvider = new JsonConfigurationProvider(this); configurationProvider.Initialize(); return configurationProvider; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationUtils.cs similarity index 72% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationUtils.cs index f9b7098ef..d13c304c1 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationUtils.cs @@ -1,25 +1,11 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace +namespace Masa.Contrib.Globalization.I18N.Json; -using Masa.BuildingBlocks.Globalization.I18N.Options; - -namespace Masa.Contrib.Globalization.I18N; - -public static class I18NOptionsExtensions +public static class JsonConfigurationUtils { - public static void UseJson(this I18NOptions _, - params LanguageInfo[] languages) - => _.UseJson(Internal.Const.DEFAULT_RESOURCE_PATH, Internal.Const.SUPPORTED_CULTURES_NAME, languages); - - public static void UseJson(this I18NOptions _, - string languageDirectory, - params LanguageInfo[] languages) - => _.UseJson(languageDirectory, Internal.Const.SUPPORTED_CULTURES_NAME, languages); - - public static void UseJson(this I18NOptions _, - string languageDirectory, + internal static void AddJson(string languageDirectory, string supportCultureName, params LanguageInfo[] languages) { @@ -52,7 +38,7 @@ private static List GetLanguageInfos( start: try { - using var fileStream = new FileStream(Path.Combine(languageDirectory, supportCultureName),FileMode.Open); + using var fileStream = new FileStream(Path.Combine(languageDirectory, supportCultureName), FileMode.Open); if (!fileStream.CanRead) { Task.Delay(300); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs new file mode 100644 index 000000000..3f4f3f501 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs @@ -0,0 +1,16 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.Contrib.Globalization.I18N; + +public class I18NOptions +{ + public IServiceCollection Services { get; } + + public I18NOptions(IServiceCollection services) + { + Services = services; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index 088934745..1498f8f2d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -8,6 +8,8 @@ global using Masa.Contrib.Globalization.I18N.Json; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.Extensions.FileProviders; global using Microsoft.Extensions.Localization; +global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj new file mode 100644 index 000000000..9a59882bf --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj @@ -0,0 +1,41 @@ + + + + net6.0 + enable + false + enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + Always + + + Always + + + Always + + + + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json new file mode 100644 index 000000000..d7e013916 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json @@ -0,0 +1,6 @@ +{ + "Name": "Jim", + "User": { + "Name": "Jim2" + } +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json new file mode 100644 index 000000000..c334e66de --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json @@ -0,0 +1,10 @@ +[ + { + "Culture": "zh-CN", + "Display": "中文简体" + }, + { + "Culture": "en-US", + "Display": "English (United States)" + } +] \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json new file mode 100644 index 000000000..c76dfe1f6 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json @@ -0,0 +1,6 @@ +{ + "Name": "吉姆", + "User": { + "Name": "Jim2" + } +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs new file mode 100644 index 000000000..79494554f --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs @@ -0,0 +1,19 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Blazor.Tests; + +[TestClass] +public class ServicesCollectionsTest +{ + [TestMethod] + public void TestAddI18NForBlazor() + { + var services = new ServiceCollection(); + services.AddI18NForBlazor(); + var descriptor = ServiceDescriptor.Transient(typeof(II18N<>), typeof(I18N<>)); + Assert.IsTrue(services.Any(d + => d.ServiceType == descriptor.ServiceType && d.Lifetime == descriptor.Lifetime && + d.ImplementationType == descriptor.ImplementationType)); + } +} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs new file mode 100644 index 000000000..095d8021c --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Globalization.I18N; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs index 13800d4a3..038c88694 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs @@ -22,10 +22,7 @@ public void TestLocalization(string cultureName, string expectedValue) { var services = new ServiceCollection(); services.AddLogging(); - services.TestAddI18N(options => - { - options.UseJson(); - }); + services.TestAddI18N(); var serviceProvider = services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); i18N.SetCulture(cultureName); @@ -43,10 +40,7 @@ public void TestLocalization(string cultureName, string expectedValue) public void TestLocalization2(string cultureName, string expectedValue) { var builder = WebApplication.CreateBuilder(); - builder.Services.TestAddI18N(options => - { - options.UseJson(DEFAULT_RESOURCE); - }); + builder.Services.TestAddI18N(DEFAULT_RESOURCE); var serviceProvider = builder.Services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); i18N.SetCulture(cultureName); @@ -63,55 +57,7 @@ public void TestLocalization2(string cultureName, string expectedValue) public void TestLocalization3(string cultureName, string expectedValue) { var builder = WebApplication.CreateBuilder(); - builder.Services.AddI18N(options => - { - options.UseJson(DEFAULT_RESOURCE); - }); - var serviceProvider = builder.Services.BuildServiceProvider(); - var i18N = serviceProvider.GetRequiredService(); - i18N.SetCulture(cultureName); - var value = i18N["Name"]; - Assert.AreEqual(expectedValue, value); - value = i18N.T("Name"); - Assert.AreEqual(expectedValue, value); - value = i18N["Name2"]; - Assert.AreEqual("Name2", value); - } - - [DataTestMethod] - [DataRow("zh-TW", "Name")] - public void TestLocalization4(string cultureName, string expectedValue) - { - var builder = WebApplication.CreateBuilder(); - builder.Services.Configure(options => - { - options.Resources - .Add() - .AddJson("/i18n"); - }); - builder.Services.AddI18N(null); - var serviceProvider = builder.Services.BuildServiceProvider(); - var i18N = serviceProvider.GetRequiredService(); - i18N.SetCulture(cultureName); - var value = i18N["Name"]; - Assert.AreEqual(expectedValue, value); - value = i18N.T("Name"); - Assert.AreEqual(expectedValue, value); - value = i18N["Name2"]; - Assert.AreEqual("Name2", value); - } - - - [DataTestMethod] - [DataRow("zh-CN", "吉姆")] - [DataRow("en-US", "Jim")] - public void TestLocalization5(string cultureName, string expectedValue) - { - var builder = WebApplication.CreateBuilder(); - builder.Services.TestAddI18N(options => - { - options.UseJson(DEFAULT_RESOURCE, new LanguageInfo("zh-CN"), new LanguageInfo("en-US")); - }); + builder.Services.AddI18N(DEFAULT_RESOURCE); var serviceProvider = builder.Services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); i18N.SetCulture(cultureName); diff --git a/src/Utils/Masa.Utils.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Utils/Masa.Utils.Exceptions/Extensions/ApplicationBuilderExtensions.cs index 284ad4b5b..5ed330801 100644 --- a/src/Utils/Masa.Utils.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Utils/Masa.Utils.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + namespace Microsoft.AspNetCore.Builder; public static class ApplicationBuilderExtensions diff --git a/src/Utils/Masa.Utils.Exceptions/Extensions/MvcBuilderExtensions.cs b/src/Utils/Masa.Utils.Exceptions/Extensions/MvcBuilderExtensions.cs index 56145ce8e..61b734129 100644 --- a/src/Utils/Masa.Utils.Exceptions/Extensions/MvcBuilderExtensions.cs +++ b/src/Utils/Masa.Utils.Exceptions/Extensions/MvcBuilderExtensions.cs @@ -2,20 +2,26 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + namespace Microsoft.Extensions.DependencyInjection; public static class MvcBuilderExtensions { public static IMvcBuilder AddMasaExceptionHandler(this IMvcBuilder builder) { - return builder.AddMasaExceptionHandler(_ => { }); + return builder.AddMasaExceptionHandler(_ => + { + }); } public static IMvcBuilder AddMasaExceptionHandler(this IMvcBuilder builder, Action action) { builder.Services.AddLocalization(); - builder.Services.Configure(options => { options.Filters.Add(); }); + builder.Services.Configure(options => + { + options.Filters.Add(); + }); builder.Services.Configure(action); diff --git a/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index 77d10fe8c..ad8587fe2 100644 --- a/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.AspNetCore.Builder; public class ExceptionHandlerMiddleware @@ -38,7 +40,7 @@ public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceP else { var masaExceptionHandler = - Masa.Utils.Exceptions.Internal.ExceptionHandlerExtensions.GetMasaExceptionHandler( + Masa.Utils.Exceptions.ExceptionHandlerExtensions.GetMasaExceptionHandler( serviceProvider, _options.MasaExceptionHandlerType); masaExceptionHandler?.OnException(masaExceptionContext); diff --git a/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlingMiddleware.cs b/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlingMiddleware.cs index a1660889c..3a7770d3a 100644 --- a/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlingMiddleware.cs +++ b/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlingMiddleware.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.AspNetCore.Builder; public class ExceptionHandlingMiddleware diff --git a/src/Utils/Masa.Utils.Exceptions/Handlers/GlobalExceptionFilter.cs b/src/Utils/Masa.Utils.Exceptions/Handlers/GlobalExceptionFilter.cs index d74c7ffa5..88f077c83 100644 --- a/src/Utils/Masa.Utils.Exceptions/Handlers/GlobalExceptionFilter.cs +++ b/src/Utils/Masa.Utils.Exceptions/Handlers/GlobalExceptionFilter.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.AspNetCore.Mvc.Filters; /// diff --git a/src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs b/src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs index 173753b75..da293c371 100644 --- a/src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs +++ b/src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace System; public interface IMasaExceptionHandler diff --git a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs b/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs index ff05ff2a7..4ead86360 100644 --- a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs +++ b/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace System; internal static class ExceptionExtensions diff --git a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs b/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs index 7d409a73f..ecd3b1a65 100644 --- a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs +++ b/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs @@ -1,7 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Utils.Exceptions.Internal; +// ReSharper disable once CheckNamespace + +namespace Masa.Utils.Exceptions; internal static class ExceptionHandlerExtensions { diff --git a/src/Utils/Masa.Utils.Exceptions/MasaException.cs b/src/Utils/Masa.Utils.Exceptions/MasaException.cs index 0afa766c7..de0adab24 100644 --- a/src/Utils/Masa.Utils.Exceptions/MasaException.cs +++ b/src/Utils/Masa.Utils.Exceptions/MasaException.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace System; [Serializable] diff --git a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs index 7f75056d0..330c88bb1 100644 --- a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs +++ b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace System; public class MasaExceptionHandlerOptions diff --git a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs index b5c69e4c7..f923670f3 100644 --- a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs +++ b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace System; public class MasaExceptionHandlingOptions diff --git a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs index 06b7d4d1f..1824bee93 100644 --- a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs +++ b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace System; public class MasaExceptionLogRelationOptions diff --git a/src/Utils/Masa.Utils.Exceptions/Results/DefaultExceptionResult.cs b/src/Utils/Masa.Utils.Exceptions/Results/DefaultExceptionResult.cs index 06999a1eb..90b3a2465 100644 --- a/src/Utils/Masa.Utils.Exceptions/Results/DefaultExceptionResult.cs +++ b/src/Utils/Masa.Utils.Exceptions/Results/DefaultExceptionResult.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.AspNetCore.Mvc; public class DefaultExceptionResult : IActionResult diff --git a/src/Utils/Masa.Utils.Exceptions/Results/InternalServerErrorObjectResult.cs b/src/Utils/Masa.Utils.Exceptions/Results/InternalServerErrorObjectResult.cs index 3540a1ef0..dbef8d291 100644 --- a/src/Utils/Masa.Utils.Exceptions/Results/InternalServerErrorObjectResult.cs +++ b/src/Utils/Masa.Utils.Exceptions/Results/InternalServerErrorObjectResult.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.AspNetCore.Mvc; public class InternalServerErrorObjectResult : ObjectResult diff --git a/src/Utils/Masa.Utils.Exceptions/Results/UserFriendlyExceptionResult.cs b/src/Utils/Masa.Utils.Exceptions/Results/UserFriendlyExceptionResult.cs index 20429d2ab..e395fb647 100644 --- a/src/Utils/Masa.Utils.Exceptions/Results/UserFriendlyExceptionResult.cs +++ b/src/Utils/Masa.Utils.Exceptions/Results/UserFriendlyExceptionResult.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.AspNetCore.Mvc; public class UserFriendlyExceptionResult : IActionResult From e64cd7c182ff839b39e338feb7dec421c4f9b693 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 31 Oct 2022 19:42:27 +0800 Subject: [PATCH 11/38] rename: Const -> Constant --- .../ServiceCollectionExtensions.cs | 4 ++-- .../Extensions/I18NOptionsExtensions.cs | 2 +- .../Internal/{Const.cs => Constant.cs} | 2 +- .../Extensions/I18NResourceExtensions.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 12 ++++++------ .../Internal/{Const.cs => Constant.cs} | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/{Const.cs => Constant.cs} (91%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/{Const.cs => Constant.cs} (91%) diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs index 70fa496cd..d0f5eef2a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs @@ -22,7 +22,7 @@ public static IServiceCollection AddI18NForBlazor( Action? action = null, params LanguageInfo[] languages) { - services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); + services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); return services.AddI18N(languageDirectory, action, languages); } @@ -33,7 +33,7 @@ public static IServiceCollection AddI18NForBlazor( Action? action = null, params LanguageInfo[] languages) { - services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); + services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); services.AddI18N(languageDirectory, supportCultureName, action, languages); return services; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index a0dd7f5db..8387adcf8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -10,7 +10,7 @@ public static class I18NOptionsExtensions public static void UseDcc( this I18NOptions i18NOptions, params LanguageInfo[] languages) - => i18NOptions.UseDcc(Dcc.Internal.Const.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Const.SUPPORTED_CULTURES_NAME, languages); + => i18NOptions.UseDcc(Dcc.Internal.Constant.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Constant.SUPPORTED_CULTURES_NAME, languages); public static void UseDcc( this I18NOptions i18NOptions, diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs similarity index 91% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs index 0b523c2da..31fc2c314 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Const.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Globalization.I18N.Dcc.Internal; -internal static class Const +internal static class Constant { internal const string DEFAULT_CONFIG_OBJECT_NAME = "i18n"; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index e4fce18cd..e6a128fa0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -51,7 +51,7 @@ private static List GetResourceContributors( ( resource.ResourceType, languageInfo.Culture, - useMasaConfiguration ? _configuration!.GetSection(SectionTypes.Local.ToString()) : _configuration! + useMasaConfiguration ? _configuration.GetSection(SectionTypes.Local.ToString()) : _configuration! ) ) .ToList(); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index 1f3fea4e9..cf8386b35 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -12,8 +12,8 @@ public static IServiceCollection AddI18N( Action? action = null, params LanguageInfo[] languages) => services.AddI18N( - Masa.Contrib.Globalization.I18N.Internal.Const.DEFAULT_RESOURCE_PATH, - Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + Masa.Contrib.Globalization.I18N.Internal.Constant.DEFAULT_RESOURCE_PATH, + Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, action, languages); @@ -24,7 +24,7 @@ public static IServiceCollection AddI18N( params LanguageInfo[] languages) => services.AddI18N( languageDirectory, - Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, action, languages); @@ -44,8 +44,8 @@ public static IServiceCollection TestAddI18N( Action? action = null, params LanguageInfo[] languages) => services.TestAddI18N( - Masa.Contrib.Globalization.I18N.Internal.Const.DEFAULT_RESOURCE_PATH, - Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + Masa.Contrib.Globalization.I18N.Internal.Constant.DEFAULT_RESOURCE_PATH, + Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, action, languages); @@ -56,7 +56,7 @@ public static IServiceCollection TestAddI18N( params LanguageInfo[] languages) => services.TestAddI18N( languageDirectory, - Masa.Contrib.Globalization.I18N.Internal.Const.SUPPORTED_CULTURES_NAME, + Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, action, languages); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs similarity index 91% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs index f08443f8a..445b1ba9e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Const.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Globalization.I18N.Internal; -internal static class Const +internal static class Constant { internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; From 6a280692fc6ab8033f0b4812f6d860f460aadcaf Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 31 Oct 2022 22:10:13 +0800 Subject: [PATCH 12/38] chore: format code --- .../I18NOfT.cs | 2 +- .../I18NOfT.cs | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs index e7dd69a1b..51a8b74c0 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs @@ -47,7 +47,7 @@ public virtual string T(string name, params object[] arguments) { ArgumentNullException.ThrowIfNull(name); - var value = this.T(name, returnKey); + var value = T(name, returnKey); if (value != null) return string.Format(GetCultureInfo(), value, arguments); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs index a05a0eaae..e72f0e7f1 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs @@ -6,22 +6,23 @@ namespace Masa.Contrib.Globalization.I18N.Blazor; [ExcludeFromCodeCoverage] public class I18N : Masa.BuildingBlocks.Globalization.I18N.I18N { - private const string CultureCookieKey = "Masa_I18nConfig_Culture"; - private readonly IJSRuntime _jsRuntime; - - public I18N(IJSRuntime jsRuntime) => _jsRuntime = jsRuntime; + private const string CULTURE_COOKIE_KEY = "Masa_I18nConfig_Culture"; - const string GetCookieJs = + private const string GET_COOKIE_JS = "(function(name){const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);const arr = document.cookie.match(reg);if (arr) {return unescape(arr[2]);}return null;})"; - const string SetCookieJs = + private const string SET_COOKIE_JS = "(function(name,value){ var Days = 30;var exp = new Date();exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);document.cookie = `${name}=${escape(value.toString())};path=/;expires=${exp.toUTCString()}`;})"; + private readonly IJSRuntime _jsRuntime; + + public I18N(IJSRuntime jsRuntime) => _jsRuntime = jsRuntime; + public override CultureInfo GetCultureInfo() { if (_jsRuntime is IJSInProcessRuntime jsInProcess) { - var cultureName = jsInProcess.Invoke("eval", $"{GetCookieJs}('{CultureCookieKey}')"); + var cultureName = jsInProcess.Invoke("eval", $"{GET_COOKIE_JS}('{CULTURE_COOKIE_KEY}')"); return new CultureInfo(cultureName); } return CultureInfo.CurrentUICulture; @@ -31,7 +32,7 @@ public override void SetCulture(CultureInfo culture) { try { - _jsRuntime.InvokeVoidAsync("eval", $"{SetCookieJs}('{CultureCookieKey}','{culture.Name}')") + _jsRuntime.InvokeVoidAsync("eval", $"{SET_COOKIE_JS}('{CULTURE_COOKIE_KEY}','{culture.Name}')") .ConfigureAwait(false) .GetAwaiter() .GetResult(); From f7b8925d8a81e199ba2a6b23dcfe83940b58598c Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 31 Oct 2022 22:37:27 +0800 Subject: [PATCH 13/38] chore: ErrorCode access level changed to private --- src/Utils/Masa.Utils.Exceptions/MasaException.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Utils/Masa.Utils.Exceptions/MasaException.cs b/src/Utils/Masa.Utils.Exceptions/MasaException.cs index de0adab24..39b501c35 100644 --- a/src/Utils/Masa.Utils.Exceptions/MasaException.cs +++ b/src/Utils/Masa.Utils.Exceptions/MasaException.cs @@ -8,9 +8,9 @@ namespace System; [Serializable] public class MasaException : Exception { - public string? ErrorCode { get; set; } + public string? ErrorCode { get; private set; } - public object[] Parameters { get; set; } + public object[] Parameters { get; private set; } public MasaException() { From 8f990314eae49e6c56fc197be78abc77814f3d1a Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Tue, 1 Nov 2022 18:30:52 +0800 Subject: [PATCH 14/38] feat(Exception): Add Exception --- Masa.Framework.sln | 14 ++ .../Constants/ErrorCode.cs | 64 +++++++++ .../Masa.BuildingBlocks.Exceptions.csproj | 13 ++ .../MasaArgumentException.cs | 130 ++++++++++++++++++ .../MasaException.cs | 45 ++++++ .../UserFriendlyException.cs | 30 ++++ .../_Imports.cs | 6 + .../MasaDefaultResource.cs | 12 ++ .../AutoCompleteDocument.cs | 9 +- ...ingBlocks.SearchEngine.AutoComplete.csproj | 4 + .../Options/AutoCompleteOptions.cs | 6 +- ...hing.Distributed.StackExchangeRedis.csproj | 1 + .../RedisCacheClient.cs | 11 +- .../Masa.Contrib.Configuration.csproj | 1 + .../Options/ConfigurationOptions.cs | 2 + .../Options/LocalMasaConfigurationOptions.cs | 2 + .../MasaAppConfigureOptionsRelation.cs | 16 +-- .../MasaConfigurationRelationOptions.cs | 2 + .../DefaultLocalDistributedLock.cs | 3 +- .../ArgumentNullOrWhiteSpaceException.cs | 15 -- ....Contrib.Data.DistributedLock.Local.csproj | 1 + .../DefaultMedallionDistributedLock.cs | 4 +- .../ArgumentNullOrWhiteSpaceException.cs | 15 -- ...trib.Data.DistributedLock.Medallion.csproj | 1 + ...ontrib.Dispatcher.IntegrationEvents.csproj | 1 + .../Options/DispatcherOptions.cs | 30 ++-- .../Internal/{Const.cs => Constant.cs} | 2 +- ...ontrib.Storage.ObjectStorage.Aliyun.csproj | 1 + .../Options/AliyunStorageOptions.cs | 2 +- .../Options/AliyunStsOptions.cs | 4 +- .../ServiceCollectionExtensions.cs | 5 +- .../StringTest.cs | 6 + 32 files changed, 374 insertions(+), 84 deletions(-) create mode 100644 src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs create mode 100644 src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj create mode 100644 src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs create mode 100644 src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaException.cs create mode 100644 src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs create mode 100644 src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/_Imports.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/MasaDefaultResource.cs delete mode 100644 src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Internal/ArgumentNullOrWhiteSpaceException.cs delete mode 100644 src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Internal/ArgumentNullOrWhiteSpaceException.cs rename src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/{Const.cs => Constant.cs} (95%) diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 99da667fd..7439f6cd9 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -626,6 +626,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exceptions", "Exceptions", "{84F366D3-6E9A-4101-AEC0-287CBA6984A8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Exceptions", "src\BuildingBlocks\Exceptions\Masa.BuildingBlocks.Exceptions\Masa.BuildingBlocks.Exceptions.csproj", "{7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2210,6 +2214,14 @@ Global {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Release|Any CPU.Build.0 = Release|Any CPU {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Release|x64.ActiveCfg = Release|Any CPU {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Release|x64.Build.0 = Release|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|x64.ActiveCfg = Debug|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|x64.Build.0 = Debug|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|Any CPU.Build.0 = Release|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|x64.ActiveCfg = Release|Any CPU + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2517,6 +2529,8 @@ Global {49B51B95-3DC5-45BD-B91A-3056FF5014B5} = {8CDAF37E-3DB1-4573-B5AA-376C93A8D299} {DD899DC4-A2B7-4C7B-A644-EDB56A61145C} = {8CDAF37E-3DB1-4573-B5AA-376C93A8D299} {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} + {84F366D3-6E9A-4101-AEC0-287CBA6984A8} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} + {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs new file mode 100644 index 000000000..dd2615644 --- /dev/null +++ b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs @@ -0,0 +1,64 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Data.Constants; + +public static class ErrorCode +{ + private const string FRAMEWORK = "MF"; + + #region Type + + private const string ARGUMENT = $"{FRAMEWORK}ARG"; + + #endregion + + #region Argument + + /// + /// + /// + public const string ARGUMENT_ERROR = $"{ARGUMENT}0001"; + + /// + /// Value cannot be null. (Parameter 'value') + /// + public const string ARGUMENT_NULL = $"{ARGUMENT}0002"; + + /// + /// Value cannot be null and empty . (Parameter 'value') + /// + public const string ARGUMENT_NULL_OR_EMPTY = $"{ARGUMENT}0003"; + + /// + /// Value cannot be null and WhiteSpace . (Parameter 'value') + /// + public const string ARGUMENT_NULL_OR_WHITE_SPACE = $"{ARGUMENT}0004"; + + /// + /// Value must be between {0}-{1} . (Parameter 'value') + /// + public const string ARGUMENT_OUT_OF_RANGE = $"{ARGUMENT}0005"; + + /// + /// Value must be greater than {0} . (Parameter 'value') + /// + public const string ARGUMENT_GREATER_THAN = $"{ARGUMENT}0006"; + + /// + /// Value must be greater than or equal {0} . (Parameter 'value') + /// + public const string ARGUMENT_GREATER_THAN_OR_EQUAL = $"{ARGUMENT}0007"; + + /// + /// Value must be less than {0} . (Parameter 'value') + /// + public const string ARGUMENT_LESS_THAN = $"{ARGUMENT}0008"; + + /// + /// Value must be less than or equal {0} . (Parameter 'value') + /// + public const string ARGUMENT_LESS_THAN_OR_EQUAL = $"{ARGUMENT}0009"; + + #endregion +} diff --git a/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj new file mode 100644 index 000000000..23f339d8f --- /dev/null +++ b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs new file mode 100644 index 000000000..7fc284791 --- /dev/null +++ b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -0,0 +1,130 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaArgumentException : MasaException2 +{ + public string? ParamName { get; } + + public MasaArgumentException(string message) + : base(message) + { + } + + public MasaArgumentException(string message, string paramName) + : base(message) + { + ParamName = paramName; + } + + public MasaArgumentException(string paramName, params object[] parameters) + : this(paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_ERROR, parameters) + { + } + + public MasaArgumentException(string? paramName, string errorCode, params object[] parameters) + : this((Exception?)null, errorCode, parameters) + { + ParamName = paramName; + } + + public MasaArgumentException(Exception? innerException, string errorCode, params object[] parameters) + : base(innerException, errorCode, parameters) + { + } + + public MasaArgumentException(string message, Exception? innerException) + : base(message, innerException) + { + } + + public MasaArgumentException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) + { + } + + public static void ThrowIfNull(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(argument is null, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL); + } + + public static void ThrowIfNullOrEmpty(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(string.IsNullOrEmpty(argument?.ToString()), + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_EMPTY); + } + + public static void ThrowIfNullOrWhiteSpace(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(argument is null, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_WHITE_SPACE); + } + + public static void ThrowIfGreaterThan(T argument, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(maxValue) > 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_LESS_THAN_OR_EQUAL, + maxValue); + } + + public static void ThrowIfGreaterThanOrEqual(T argument, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(maxValue) >= 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_LESS_THAN, + maxValue); + } + + public static void ThrowIfLessThan(T argument, + T minValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) < 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_GREATER_THAN_OR_EQUAL, + minValue); + } + + public static void ThrowIfLessThanOrEqual(T argument, + T minValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) <= 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_GREATER_THAN, + minValue); + } + + public static void ThrowIfOutOfRange(T argument, + T minValue, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) < 0 || argument.CompareTo(maxValue) > 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_OUT_OF_RANGE, + minValue, + maxValue); + } + + public static void ThrowIf(bool condition, string? paramName, string errorCode, params object[] parameters) + { + if (condition) Throw(paramName, errorCode, parameters); + } + + [DoesNotReturn] + private static void Throw(string? paramName, string errorCode, params object[] parameters) => + throw new MasaArgumentException(paramName, errorCode, parameters); +} diff --git a/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaException.cs new file mode 100644 index 000000000..efc67d588 --- /dev/null +++ b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -0,0 +1,45 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +[Serializable] +public class MasaException2 : Exception +{ + public string? ErrorCode { get; private set; } + + public object[] Parameters { get; private set; } + + public MasaException2() + { + } + + public MasaException2(string message) + : base(message) + { + } + + public MasaException2(string errorCode, params object[] parameters) + : this(null, errorCode, parameters) + { + } + + public MasaException2(Exception? innerException, string errorCode, params object[] parameters) + : base(null, innerException) + { + ErrorCode = errorCode; + Parameters = parameters; + } + + public MasaException2(string message, Exception? innerException) + : base(message, innerException) + { + } + + public MasaException2(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) + { + } +} diff --git a/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs new file mode 100644 index 000000000..b07eaa522 --- /dev/null +++ b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs @@ -0,0 +1,30 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +[Serializable] +public class UserFriendlyException2 : MasaException2 +{ + public UserFriendlyException2(string message) + : base(message) + { + } + + public UserFriendlyException2(string message, Exception? innerException) + : base(message, innerException) + { + } + + public UserFriendlyException2(string errorCode, params object[] parameters) + : base(errorCode, parameters) + { + } + + public UserFriendlyException2(Exception? innerException, string errorCode, params object[] parameters) + : base(innerException, errorCode, parameters) + { + } +} diff --git a/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/_Imports.cs b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/_Imports.cs new file mode 100644 index 000000000..fa282e19c --- /dev/null +++ b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/_Imports.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using System.Diagnostics.CodeAnalysis; +global using System.Runtime.Serialization; +global using System.Runtime.CompilerServices; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/MasaDefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/MasaDefaultResource.cs new file mode 100644 index 000000000..2ba555410 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/MasaDefaultResource.cs @@ -0,0 +1,12 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +/// +/// Framework Multilingual Resources +/// +public class MasaDefaultResource +{ + +} diff --git a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/AutoCompleteDocument.cs b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/AutoCompleteDocument.cs index 0a5e5f34b..863999d03 100644 --- a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/AutoCompleteDocument.cs +++ b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/AutoCompleteDocument.cs @@ -45,14 +45,17 @@ public string Id get { if (string.IsNullOrEmpty(_id)) - return Value?.ToString() ?? throw new ArgumentException($"{nameof(Id)} cannot be empty", nameof(Id)); + { + var val = Value.ToString(); + MasaArgumentException.ThrowIfNullOrEmpty(val, nameof(Id)); + return val!; + } return _id; } init { - if (string.IsNullOrEmpty(value)) - throw new ArgumentException($"{nameof(Id)} cannot be empty", nameof(Id)); + MasaArgumentException.ThrowIfNullOrEmpty(value, nameof(Id)); _id = value; } diff --git a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj index ca62071d4..9cc0b6689 100644 --- a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj +++ b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Options/AutoCompleteOptions.cs b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Options/AutoCompleteOptions.cs index 98e26886c..a0794c1f3 100644 --- a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Options/AutoCompleteOptions.cs +++ b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Options/AutoCompleteOptions.cs @@ -14,8 +14,7 @@ public int Page get => _page; set { - if (value <= 0) - throw new ArgumentException($"{nameof(Page)} must be greater than 0", nameof(Page)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(Page)); _page = value; } @@ -28,8 +27,7 @@ public int PageSize get => _pageSize; set { - if (value <= 0) - throw new ArgumentException($"{nameof(PageSize)} must be greater than 0", nameof(PageSize)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(PageSize)); _pageSize = value; } diff --git a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj index 122f651b0..4bd7276f4 100644 --- a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj +++ b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClient.cs b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClient.cs index 845183ab3..0720791b3 100644 --- a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClient.cs +++ b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClient.cs @@ -400,7 +400,7 @@ public override async Task HashIncrementAsync( Action? action = null, CacheEntryOptions? options = null) { - CheckParametersByHashIncrementOrHashDecrement(value); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0L); var script = $@" local exist = redis.call('EXISTS', KEYS[1]) @@ -423,11 +423,6 @@ public override async Task HashIncrementAsync( return result; } - private static void CheckParametersByHashIncrementOrHashDecrement(long value = 1) - { - if (value < 1) throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(value)} must be greater than 0"); - } - /// /// Descending Hash /// @@ -444,7 +439,7 @@ private static void CheckParametersByHashIncrementOrHashDecrement(long value = 1 Action? action = null, CacheEntryOptions? options = null) { - CheckParametersByHashIncrementOrHashDecrement(value); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0L); var script = $@" local exist = redis.call('EXISTS', KEYS[1]) @@ -469,7 +464,7 @@ private static void CheckParametersByHashIncrementOrHashDecrement(long value = 1 var formattedKey = FormatCacheKey(key, action); var result = await Db.ScriptEvaluateAsync( script, - new RedisKey[] { formattedKey, Const.DATA_KEY , Const.ABSOLUTE_EXPIRATION_KEY, Const.SLIDING_EXPIRATION_KEY }, + new RedisKey[] { formattedKey, Const.DATA_KEY, Const.ABSOLUTE_EXPIRATION_KEY, Const.SLIDING_EXPIRATION_KEY }, GetRedisValues(options)); await RefreshAsync(formattedKey); diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj b/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj index fbe7d581b..643f82176 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/ConfigurationOptions.cs b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/ConfigurationOptions.cs index 92debe9c6..ba17f9853 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/ConfigurationOptions.cs +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/ConfigurationOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Masa.Contrib.Configuration; public class ConfigurationOptions diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/LocalMasaConfigurationOptions.cs b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/LocalMasaConfigurationOptions.cs index f77e56bbc..f3bb5d3f3 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/LocalMasaConfigurationOptions.cs +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/LocalMasaConfigurationOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Masa.Contrib.Configuration; public abstract class LocalMasaConfigurationOptions : MasaConfigurationOptions diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaAppConfigureOptionsRelation.cs b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaAppConfigureOptionsRelation.cs index 43fc8def5..2a22559e8 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaAppConfigureOptionsRelation.cs +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaAppConfigureOptionsRelation.cs @@ -1,7 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Configuration.Options; +// ReSharper disable once CheckNamespace + +namespace Masa.BuildingBlocks.Configuration; public class MasaAppConfigureOptionsRelation { @@ -29,14 +31,11 @@ public MasaAppConfigureOptionsRelation() public MasaAppConfigureOptionsRelation SetOptionsRelation(string key, string variable, string defaultValue) { - if (string.IsNullOrEmpty(key)) - throw new ArgumentException($"{nameof(key)} cannot be empty", nameof(key)); + MasaArgumentException.ThrowIfNullOrEmpty(key); - if (string.IsNullOrEmpty(variable)) - throw new ArgumentException($"{nameof(variable)} cannot be empty", nameof(variable)); + MasaArgumentException.ThrowIfNullOrEmpty(variable); - if (string.IsNullOrEmpty(defaultValue)) - throw new ArgumentException($"{nameof(defaultValue)} cannot be empty", nameof(defaultValue)); + MasaArgumentException.ThrowIfNullOrEmpty(defaultValue); Data[key] = (variable, defaultValue); return this; @@ -46,8 +45,7 @@ public MasaAppConfigureOptionsRelation SetOptionsRelation(string key, string var internal (string Variable, string DefaultValue) GetValue(string key) { - if (string.IsNullOrEmpty(key)) - throw new ArgumentException($"{nameof(key)} cannot be empty", nameof(key)); + MasaArgumentException.ThrowIfNullOrEmpty(key); return Data[key]; } diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaConfigurationRelationOptions.cs b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaConfigurationRelationOptions.cs index eeae8c588..464861b9c 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaConfigurationRelationOptions.cs +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Options/MasaConfigurationRelationOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Masa.Contrib.Configuration; public class MasaConfigurationRelationOptions diff --git a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/DefaultLocalDistributedLock.cs b/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/DefaultLocalDistributedLock.cs index 9d87952e2..c21525434 100644 --- a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/DefaultLocalDistributedLock.cs +++ b/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/DefaultLocalDistributedLock.cs @@ -33,7 +33,8 @@ public class DefaultLocalDistributedLock : IDistributedLock private SemaphoreSlim GetSemaphoreSlim(string key) { - ArgumentNullOrWhiteSpaceException.ThrowIfNullOrWhiteSpace(key); + MasaArgumentException.ThrowIfNullOrWhiteSpace(key); + return _localObjects.GetOrAdd(key, _ => new SemaphoreSlim(1, 1)); } } diff --git a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Internal/ArgumentNullOrWhiteSpaceException.cs b/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Internal/ArgumentNullOrWhiteSpaceException.cs deleted file mode 100644 index 6246faf3a..000000000 --- a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Internal/ArgumentNullOrWhiteSpaceException.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Data.DistributedLock.Local.Internal; - -internal static class ArgumentNullOrWhiteSpaceException -{ - public static void ThrowIfNullOrWhiteSpace(string? argument, string? paramName = null) - { - paramName ??= nameof(argument); - - if (string.IsNullOrWhiteSpace(argument)) - throw new ArgumentException($"{paramName} can not be null, empty or white space!", paramName); - } -} diff --git a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj b/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj index a02b6a725..5cd3b0af3 100644 --- a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj +++ b/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/DefaultMedallionDistributedLock.cs b/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/DefaultMedallionDistributedLock.cs index f8cd492fa..61b1aad8d 100644 --- a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/DefaultMedallionDistributedLock.cs +++ b/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/DefaultMedallionDistributedLock.cs @@ -12,7 +12,7 @@ public DefaultMedallionDistributedLock(IDistributedLockProvider distributedLockP public IDisposable? TryGet(string key, TimeSpan timeout = default) { - ArgumentNullOrWhiteSpaceException.ThrowIfNullOrWhiteSpace(key); + MasaArgumentException.ThrowIfNullOrWhiteSpace(key); var handle = _distributedLockProvider.TryAcquireLock(key, timeout); if (handle == null) return null; @@ -22,7 +22,7 @@ public DefaultMedallionDistributedLock(IDistributedLockProvider distributedLockP public async Task TryGetAsync(string key, TimeSpan timeout = default, CancellationToken cancellationToken = default) { - ArgumentNullOrWhiteSpaceException.ThrowIfNullOrWhiteSpace(key); + MasaArgumentException.ThrowIfNullOrWhiteSpace(key); var handle = await _distributedLockProvider.TryAcquireLockAsync(key, timeout, cancellationToken); if (handle == null) return null; diff --git a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Internal/ArgumentNullOrWhiteSpaceException.cs b/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Internal/ArgumentNullOrWhiteSpaceException.cs deleted file mode 100644 index 95687b703..000000000 --- a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Internal/ArgumentNullOrWhiteSpaceException.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Data.DistributedLock.Medallion.Internal; - -internal static class ArgumentNullOrWhiteSpaceException -{ - public static void ThrowIfNullOrWhiteSpace(string? argument, string? paramName = null) - { - paramName ??= nameof(argument); - - if (string.IsNullOrWhiteSpace(argument)) - throw new ArgumentException($"{paramName} can not be null, empty or white space!", paramName); - } -} diff --git a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj b/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj index fa0c30832..99a45475c 100644 --- a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj +++ b/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj index 14b7bf1d2..bd85c9df9 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj +++ b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs index 383659973..18c650cd3 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs +++ b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs @@ -19,8 +19,7 @@ public int LocalRetryTimes get => _localRetryTimes; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(LocalRetryTimes)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(LocalRetryTimes)); _localRetryTimes = value; } @@ -37,8 +36,7 @@ public int MaxRetryTimes get => _maxRetryTimes; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(MaxRetryTimes)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(MaxRetryTimes)); _maxRetryTimes = value; } @@ -56,8 +54,7 @@ public int FailedRetryInterval get => _failedRetryInterval; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(FailedRetryInterval)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(FailedRetryInterval)); _failedRetryInterval = value; } @@ -74,8 +71,7 @@ public int MinimumRetryInterval get => _minimumRetryInterval; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(MinimumRetryInterval)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(MinimumRetryInterval)); _minimumRetryInterval = value; } @@ -94,8 +90,7 @@ public int LocalFailedRetryInterval get => _localFailedRetryInterval; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(LocalFailedRetryInterval)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(LocalFailedRetryInterval)); _localFailedRetryInterval = value; } @@ -111,8 +106,7 @@ public int RetryBatchSize get => _retryBatchSize; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(RetryBatchSize)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(RetryBatchSize)); _retryBatchSize = value; } @@ -130,8 +124,7 @@ public int CleaningLocalQueueExpireInterval get => _cleaningLocalQueueExpireInterval; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(CleaningLocalQueueExpireInterval)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(CleaningLocalQueueExpireInterval)); _cleaningLocalQueueExpireInterval = value; } @@ -149,8 +142,7 @@ public int CleaningExpireInterval get => _cleaningExpireInterval; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(CleaningExpireInterval)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(CleaningExpireInterval)); _cleaningExpireInterval = value; } @@ -167,8 +159,7 @@ public long PublishedExpireTime get => _publishedExpireTime; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(PublishedExpireTime)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(PublishedExpireTime)); _publishedExpireTime = value; } @@ -184,8 +175,7 @@ public int DeleteBatchCount get => _deleteBatchCount; set { - if (value <= 0) - throw new ArgumentException("must be greater than 0", nameof(DeleteBatchCount)); + MasaArgumentException.ThrowIfLessThanOrEqual(value, 0, nameof(DeleteBatchCount)); _deleteBatchCount = value; } diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/Const.cs b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/Constant.cs similarity index 95% rename from src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/Const.cs rename to src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/Constant.cs index 9e26a82d3..e777f53b7 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/Const.cs +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/Constant.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Storage.ObjectStorage.Aliyun.Internal; -internal static class Const +internal static class Constant { public const string TEMPORARY_CREDENTIALS_CACHEKEY = "Aliyun.Storage.TemporaryCredentials"; diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj index 1643603e5..54461bb27 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStorageOptions.cs b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStorageOptions.cs index ea920f0b8..e52dc6c69 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStorageOptions.cs +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStorageOptions.cs @@ -15,7 +15,7 @@ public string Endpoint set => _endpoint = value?.Trim() ?? string.Empty; } - private string _temporaryCredentialsCacheKey = Const.TEMPORARY_CREDENTIALS_CACHEKEY; + private string _temporaryCredentialsCacheKey = Constant.TEMPORARY_CREDENTIALS_CACHEKEY; public string TemporaryCredentialsCacheKey { diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStsOptions.cs b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStsOptions.cs index 3cdff636e..5ef4403b0 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStsOptions.cs +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Options/AliyunStsOptions.cs @@ -56,7 +56,7 @@ public AliyunStsOptions(string? regionId = null) RegionId = regionId; } - public long GetDurationSeconds() => DurationSeconds ?? Const.DEFAULT_DURATION_SECONDS; + public long GetDurationSeconds() => DurationSeconds ?? Constant.DEFAULT_DURATION_SECONDS; - public long GetEarlyExpires() => EarlyExpires ?? Const.DEFAULT_EARLY_EXPIRES; + public long GetEarlyExpires() => EarlyExpires ?? Constant.DEFAULT_EARLY_EXPIRES; } diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs index 5c9c21d03..698bbc50f 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs @@ -16,10 +16,9 @@ public static class ServiceCollectionExtensions /// public static IServiceCollection AddAliyunStorage( this IServiceCollection services, - string sectionName = Const.DEFAULT_SECTION) + string sectionName = Constant.DEFAULT_SECTION) { - if (string.IsNullOrEmpty(sectionName)) - throw new ArgumentException(sectionName, nameof(sectionName)); + MasaArgumentException.ThrowIfNullOrEmpty(sectionName); services.AddConfigure($"{sectionName}{ConfigurationPath.KeyDelimiter}{nameof(AliyunStorageConfigureOptions.Storage)}"); services.AddConfigure(sectionName); diff --git a/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs b/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs index 9a9220ef3..63842d040 100644 --- a/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs +++ b/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs @@ -21,4 +21,10 @@ public void TestTrimEnd(string value, string trimParameter, string result) { Assert.AreEqual(result, value.TrimEnd(trimParameter, StringComparison.OrdinalIgnoreCase)); } + + [TestMethod] + public void Test() + { + + } } From da8c5a680d1e8892b5ea30f6f712cc687a2256eb Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 2 Nov 2022 10:31:02 +0800 Subject: [PATCH 15/38] refactor(Exception): Refactor Exception --- Masa.Framework.sln | 36 +++-- .../Masa.BuildingBlocks.Exceptions.csproj | 13 ++ .../MasaArgumentException.cs | 130 ++++++++++++++++++ .../MasaException.cs | 45 ++++++ .../MasaHttpStatusCode.cs | 11 ++ .../UserFriendlyException.cs | 30 ++++ .../_Imports.cs | 6 + .../IMasaExceptionHandler.cs | 11 ++ .../MasaExceptionContext.cs | 52 +++++++ ...ingBlocks.SearchEngine.AutoComplete.csproj | 2 +- .../Masa.BuildingBlocks.Service.Caller.csproj | 1 + ...hing.Distributed.StackExchangeRedis.csproj | 2 +- .../Masa.Contrib.Configuration.csproj | 3 +- ....Contrib.Data.DistributedLock.Local.csproj | 2 +- ...trib.Data.DistributedLock.Medallion.csproj | 3 +- ....Contrib.Data.IdGenerator.Snowflake.csproj | 12 +- ...ontrib.Dispatcher.IntegrationEvents.csproj | 9 +- .../_Imports.cs | 1 - .../IMasaExceptionHandler.cs | 11 ++ .../Internal/Constant.cs | 11 ++ .../Internal/ExceptionExtensions.cs | 20 +++ .../Internal/ExceptionHandlerExtensions.cs | 31 +++++ .../Internal/HttpResponseExtensions.cs | 26 ++++ .../Masa.Contrib.Exceptions.csproj | 17 +++ .../MasaExceptionContext.cs | 52 +++++++ .../Options/MasaExceptionHandlerOptions.cs | 20 +++ .../Options/MasaExceptionHandlingOptions.cs | 13 ++ .../MasaExceptionLogRelationOptions.cs | 25 ++++ .../Masa.Contrib.Exceptions/_Imports.cs | 10 ++ .../Masa.Contrib.Service.Caller.csproj | 8 +- .../Masa.Contrib.Service.Caller/_Imports.cs | 1 - .../_Imports.cs | 1 - ...ontrib.Storage.ObjectStorage.Aliyun.csproj | 2 +- 33 files changed, 584 insertions(+), 33 deletions(-) create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs create mode 100644 src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/IMasaExceptionHandler.cs create mode 100644 src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaExceptionContext.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/IMasaExceptionHandler.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 7439f6cd9..b4ee276ce 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -626,9 +626,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exceptions", "Exceptions", "{84F366D3-6E9A-4101-AEC0-287CBA6984A8}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exception", "Exception", "{84F366D3-6E9A-4101-AEC0-287CBA6984A8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Exceptions", "src\BuildingBlocks\Exceptions\Masa.BuildingBlocks.Exceptions\Masa.BuildingBlocks.Exceptions.csproj", "{7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exception", "Exception", "{F17FFB29-A622-4430-B2EA-E9FF20E68122}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Exceptions", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions\Masa.BuildingBlocks.Exceptions.csproj", "{145400E0-7AC3-4D7B-88D1-F17847E4FA6D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Exceptions", "src\Contrib\Exception\Masa.Contrib.Exceptions\Masa.Contrib.Exceptions.csproj", "{C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -2214,14 +2218,22 @@ Global {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Release|Any CPU.Build.0 = Release|Any CPU {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Release|x64.ActiveCfg = Release|Any CPU {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Release|x64.Build.0 = Release|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|x64.ActiveCfg = Debug|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Debug|x64.Build.0 = Debug|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|Any CPU.Build.0 = Release|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|x64.ActiveCfg = Release|Any CPU - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED}.Release|x64.Build.0 = Release|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Debug|x64.ActiveCfg = Debug|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Debug|x64.Build.0 = Debug|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Release|Any CPU.Build.0 = Release|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Release|x64.ActiveCfg = Release|Any CPU + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D}.Release|x64.Build.0 = Release|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Debug|x64.ActiveCfg = Debug|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Debug|x64.Build.0 = Debug|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|Any CPU.Build.0 = Release|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|x64.ActiveCfg = Release|Any CPU + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2530,7 +2542,9 @@ Global {DD899DC4-A2B7-4C7B-A644-EDB56A61145C} = {8CDAF37E-3DB1-4573-B5AA-376C93A8D299} {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} {84F366D3-6E9A-4101-AEC0-287CBA6984A8} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} - {7C003EAC-4AD5-4F2A-A85D-71DDAC7B3AED} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} + {F17FFB29-A622-4430-B2EA-E9FF20E68122} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} + {145400E0-7AC3-4D7B-88D1-F17847E4FA6D} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} + {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48} = {F17FFB29-A622-4430-B2EA-E9FF20E68122} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj new file mode 100644 index 000000000..b3d41f5ba --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs new file mode 100644 index 000000000..6068e45cf --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -0,0 +1,130 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaArgumentException : MasaException +{ + public string? ParamName { get; } + + public MasaArgumentException(string message) + : base(message) + { + } + + public MasaArgumentException(string message, string paramName) + : base(message) + { + ParamName = paramName; + } + + public MasaArgumentException(string paramName, params object[] parameters) + : this(paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_ERROR, parameters) + { + } + + public MasaArgumentException(string? paramName, string errorCode, params object[] parameters) + : this((Exception?)null, errorCode, parameters) + { + ParamName = paramName; + } + + public MasaArgumentException(Exception? innerException, string errorCode, params object[] parameters) + : base(innerException, errorCode, parameters) + { + } + + public MasaArgumentException(string message, Exception? innerException) + : base(message, innerException) + { + } + + public MasaArgumentException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) + { + } + + public static void ThrowIfNull(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(argument is null, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL); + } + + public static void ThrowIfNullOrEmpty(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(string.IsNullOrEmpty(argument?.ToString()), + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_EMPTY); + } + + public static void ThrowIfNullOrWhiteSpace(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(argument is null, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_WHITE_SPACE); + } + + public static void ThrowIfGreaterThan(T argument, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(maxValue) > 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_LESS_THAN_OR_EQUAL, + maxValue); + } + + public static void ThrowIfGreaterThanOrEqual(T argument, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(maxValue) >= 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_LESS_THAN, + maxValue); + } + + public static void ThrowIfLessThan(T argument, + T minValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) < 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_GREATER_THAN_OR_EQUAL, + minValue); + } + + public static void ThrowIfLessThanOrEqual(T argument, + T minValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) <= 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_GREATER_THAN, + minValue); + } + + public static void ThrowIfOutOfRange(T argument, + T minValue, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) < 0 || argument.CompareTo(maxValue) > 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_OUT_OF_RANGE, + minValue, + maxValue); + } + + public static void ThrowIf(bool condition, string? paramName, string errorCode, params object[] parameters) + { + if (condition) Throw(paramName, errorCode, parameters); + } + + [DoesNotReturn] + private static void Throw(string? paramName, string errorCode, params object[] parameters) => + throw new MasaArgumentException(paramName, errorCode, parameters); +} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs new file mode 100644 index 000000000..39b501c35 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -0,0 +1,45 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +[Serializable] +public class MasaException : Exception +{ + public string? ErrorCode { get; private set; } + + public object[] Parameters { get; private set; } + + public MasaException() + { + } + + public MasaException(string message) + : base(message) + { + } + + public MasaException(string errorCode, params object[] parameters) + : this(null, errorCode, parameters) + { + } + + public MasaException(Exception? innerException, string errorCode, params object[] parameters) + : base(null, innerException) + { + ErrorCode = errorCode; + Parameters = parameters; + } + + public MasaException(string message, Exception? innerException) + : base(message, innerException) + { + } + + public MasaException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) + { + } +} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs new file mode 100644 index 000000000..2010c5e75 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public enum MasaHttpStatusCode +{ + UserFriendlyException = 299 +} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs new file mode 100644 index 000000000..dedf96fc8 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs @@ -0,0 +1,30 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +[Serializable] +public class UserFriendlyException : MasaException +{ + public UserFriendlyException(string message) + : base(message) + { + } + + public UserFriendlyException(string message, Exception? innerException) + : base(message, innerException) + { + } + + public UserFriendlyException(string errorCode, params object[] parameters) + : base(errorCode, parameters) + { + } + + public UserFriendlyException(Exception? innerException, string errorCode, params object[] parameters) + : base(innerException, errorCode, parameters) + { + } +} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs new file mode 100644 index 000000000..fa282e19c --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using System.Diagnostics.CodeAnalysis; +global using System.Runtime.Serialization; +global using System.Runtime.CompilerServices; diff --git a/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/IMasaExceptionHandler.cs b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/IMasaExceptionHandler.cs new file mode 100644 index 000000000..da293c371 --- /dev/null +++ b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/IMasaExceptionHandler.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public interface IMasaExceptionHandler +{ + void OnException(MasaExceptionContext context); +} diff --git a/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaExceptionContext.cs b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaExceptionContext.cs new file mode 100644 index 000000000..cd4735f09 --- /dev/null +++ b/src/BuildingBlocks/Exceptions/Masa.BuildingBlocks.Exceptions/MasaExceptionContext.cs @@ -0,0 +1,52 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaExceptionContext +{ + public IServiceProvider ServiceProvider { get; set; } + + public Exception Exception { get; set; } + + public HttpContext HttpContext { get; } + + public bool ExceptionHandled { get; set; } + + /// + /// Http status code + /// + public int StatusCode { get; set; } + + /// + /// Error code to provide support for subsequent I18n + /// + public string? ErrorCode { get; set; } + + public string? Message { get; set; } + + public string ContentType { get; set; } + + internal MasaExceptionContext(Exception exception, HttpContext httpContext, IServiceProvider serviceProvider) + { + Exception = exception; + HttpContext = httpContext; + StatusCode = (int)MasaHttpStatusCode.UserFriendlyException; + ExceptionHandled = false; + ContentType = Constant.DEFAULT_HTTP_CONTENT_TYPE; + ServiceProvider = serviceProvider; + } + + public void ToResult( + string message, + int statusCode = (int)MasaHttpStatusCode.UserFriendlyException, + string contentType = Constant.DEFAULT_HTTP_CONTENT_TYPE) + { + Message = message; + StatusCode = statusCode; + ExceptionHandled = true; + ContentType = contentType; + } +} diff --git a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj index 9cc0b6689..93622815f 100644 --- a/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj +++ b/src/BuildingBlocks/SearchEngine/Masa.BuildingBlocks.SearchEngine.AutoComplete/Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/BuildingBlocks/Service/Masa.BuildingBlocks.Service.Caller/Masa.BuildingBlocks.Service.Caller.csproj b/src/BuildingBlocks/Service/Masa.BuildingBlocks.Service.Caller/Masa.BuildingBlocks.Service.Caller.csproj index 2bcff12c4..06ac63c9e 100644 --- a/src/BuildingBlocks/Service/Masa.BuildingBlocks.Service.Caller/Masa.BuildingBlocks.Service.Caller.csproj +++ b/src/BuildingBlocks/Service/Masa.BuildingBlocks.Service.Caller/Masa.BuildingBlocks.Service.Caller.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj index 4bd7276f4..ca8d6d996 100644 --- a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj +++ b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/Masa.Contrib.Caching.Distributed.StackExchangeRedis.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj b/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj index 643f82176..3f18f6c7b 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Masa.Contrib.Configuration.csproj @@ -13,8 +13,7 @@ - - + diff --git a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj b/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj index 5cd3b0af3..b3a8081c6 100644 --- a/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj +++ b/src/Contrib/Data/DistributedLock/Masa.Contrib.Data.DistributedLock.Local/Masa.Contrib.Data.DistributedLock.Local.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj b/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj index 99a45475c..c803b56fb 100644 --- a/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj +++ b/src/Contrib/Data/DistributedLock/Medallion/Masa.Contrib.Data.DistributedLock.Medallion/Masa.Contrib.Data.DistributedLock.Medallion.csproj @@ -12,9 +12,8 @@ - + - diff --git a/src/Contrib/Data/IdGenerator/Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake.csproj b/src/Contrib/Data/IdGenerator/Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake.csproj index 0f3f82acd..99f8caf01 100644 --- a/src/Contrib/Data/IdGenerator/Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake.csproj +++ b/src/Contrib/Data/IdGenerator/Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake/Masa.Contrib.Data.IdGenerator.Snowflake.csproj @@ -5,11 +5,15 @@ enable enable - + + + + + - - - + + + diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj index bd85c9df9..258c2a705 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj +++ b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.csproj @@ -7,14 +7,13 @@ - + + - - - - + + diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/_Imports.cs b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/_Imports.cs index 06f358aeb..d65ba3493 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/_Imports.cs +++ b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/_Imports.cs @@ -11,7 +11,6 @@ global using Masa.Contrib.Dispatcher.IntegrationEvents.Options; global using Masa.Contrib.Dispatcher.IntegrationEvents.Processor; global using Masa.Contrib.Dispatcher.IntegrationEvents.Servers; -global using Masa.Utils.Models.Config; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.Extensions.Hosting; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/IMasaExceptionHandler.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/IMasaExceptionHandler.cs new file mode 100644 index 000000000..da293c371 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/IMasaExceptionHandler.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public interface IMasaExceptionHandler +{ + void OnException(MasaExceptionContext context); +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs new file mode 100644 index 000000000..bfce3e65e --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Exceptions.Internal; + +internal static class Constant +{ + public const string DEFAULT_HTTP_CONTENT_TYPE = "text/plain; charset=utf-8"; + + public const string DEFAULT_EXCEPTION_MESSAGE = "An error occur in masa framework."; +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs new file mode 100644 index 000000000..4ead86360 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +internal static class ExceptionExtensions +{ + public static void WriteLog( + this ILogger logger, + Exception exception, + LogLevel defaultLogLevel, + MasaExceptionLogRelationOptions logRelationOptions, + string? message = null) + { + var logLevel = logRelationOptions.GetLogLevel(exception, defaultLogLevel); + logger.Log(logLevel, exception, message ?? exception.Message); + } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs new file mode 100644 index 000000000..c611cd0a4 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs @@ -0,0 +1,31 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Exceptions.Internal; + +internal static class ExceptionHandlerExtensions +{ + public static IMasaExceptionHandler? GetMasaExceptionHandler(IServiceProvider serviceProvider, Type? masaExceptionHandlerType) + { + var exceptionHandler = serviceProvider.GetService(); + if (exceptionHandler != null) + return exceptionHandler; + + if (masaExceptionHandlerType == null) + return null; + + var constructor = masaExceptionHandlerType.GetConstructors(BindingFlags.Instance | BindingFlags.Public) + .MaxBy(c => c.GetParameters().Length); + List parameters = new(); + if (constructor != null) + { + foreach (var parameterInfo in constructor.GetParameters()) + parameters.Add(serviceProvider.GetService(parameterInfo.ParameterType)); + } + var instance = Activator.CreateInstance(masaExceptionHandlerType, parameters.ToArray()); + if (instance != null) + return instance as IMasaExceptionHandler; + + return null; + } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs new file mode 100644 index 000000000..4921668cb --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs @@ -0,0 +1,26 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Exceptions.Internal; + +internal static class HttpResponseExtensions +{ + /// + /// Write response with text/plain + /// + /// + /// + /// + /// + /// + public static async Task WriteTextAsync( + this HttpResponse httpResponse, + int statusCode, + string text, + string contentType = "text/plain; charset=utf-8") + { + httpResponse.StatusCode = statusCode; + httpResponse.ContentType = contentType; + await httpResponse.WriteAsync(text, Encoding.UTF8); + } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj new file mode 100644 index 000000000..349dcb244 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs new file mode 100644 index 000000000..cd4735f09 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs @@ -0,0 +1,52 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaExceptionContext +{ + public IServiceProvider ServiceProvider { get; set; } + + public Exception Exception { get; set; } + + public HttpContext HttpContext { get; } + + public bool ExceptionHandled { get; set; } + + /// + /// Http status code + /// + public int StatusCode { get; set; } + + /// + /// Error code to provide support for subsequent I18n + /// + public string? ErrorCode { get; set; } + + public string? Message { get; set; } + + public string ContentType { get; set; } + + internal MasaExceptionContext(Exception exception, HttpContext httpContext, IServiceProvider serviceProvider) + { + Exception = exception; + HttpContext = httpContext; + StatusCode = (int)MasaHttpStatusCode.UserFriendlyException; + ExceptionHandled = false; + ContentType = Constant.DEFAULT_HTTP_CONTENT_TYPE; + ServiceProvider = serviceProvider; + } + + public void ToResult( + string message, + int statusCode = (int)MasaHttpStatusCode.UserFriendlyException, + string contentType = Constant.DEFAULT_HTTP_CONTENT_TYPE) + { + Message = message; + StatusCode = statusCode; + ExceptionHandled = true; + ContentType = contentType; + } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs new file mode 100644 index 000000000..330c88bb1 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaExceptionHandlerOptions +{ + public bool CatchAllException { get; set; } = true; + + public Action? ExceptionHandler { get; set; } + + internal Type? MasaExceptionHandlerType { get; private set; } + + public void UseExceptionHanlder() where TExceptionHanlder : IMasaExceptionHandler + { + MasaExceptionHandlerType = typeof(TExceptionHanlder); + } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs new file mode 100644 index 000000000..f923670f3 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs @@ -0,0 +1,13 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaExceptionHandlingOptions +{ + public bool CatchAllException { get; set; } = true; + + public Func? CustomExceptionHandler { get; set; } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs new file mode 100644 index 000000000..1824bee93 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs @@ -0,0 +1,25 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaExceptionLogRelationOptions +{ + internal Dictionary Mappings { get; } = new(); + + public MasaExceptionLogRelationOptions MapLogLevel(LogLevel logLevel) where TException : Exception + { + Mappings[typeof(TException)] = logLevel; + return this; + } + + internal LogLevel GetLogLevel(Exception exception, LogLevel defaultLogLevel) + { + if (!Mappings.TryGetValue(exception.GetType(), out var logLevel)) + logLevel = defaultLogLevel; + + return logLevel; + } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs new file mode 100644 index 000000000..7dbbc7168 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs @@ -0,0 +1,10 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.Contrib.Exceptions; +global using Microsoft.AspNetCore.Http; +global using Microsoft.Extensions.Logging; +global using System.Text; +global using System.Reflection; +global using Microsoft.Extensions.DependencyInjection; +global using Masa.Contrib.Exceptions.Internal; diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/Masa.Contrib.Service.Caller.csproj b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/Masa.Contrib.Service.Caller.csproj index caebe44cc..51cf247b4 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/Masa.Contrib.Service.Caller.csproj +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/Masa.Contrib.Service.Caller.csproj @@ -7,8 +7,12 @@ - - + + + + + + diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs index f6eb18cab..cbd8cef90 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs @@ -6,7 +6,6 @@ global using Masa.BuildingBlocks.Service.Caller.Options; global using Masa.Contrib.Service.Caller.Internal; global using Masa.Contrib.Service.Caller.Internal.Options; -global using Masa.Utils.Exceptions; global using Microsoft.AspNetCore.Http; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs index 7d230833d..6ef3ae1cd 100644 --- a/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs +++ b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs @@ -8,7 +8,6 @@ global using Masa.Contrib.Service.Caller.Tests.Queries; global using Masa.Contrib.Service.Caller.Tests.Requesties; global using Masa.Contrib.Service.Caller.Tests.Response; -global using Masa.Utils.Exceptions; global using Microsoft.AspNetCore.Builder; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj index 54461bb27..3a7add0f8 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Masa.Contrib.Storage.ObjectStorage.Aliyun.csproj @@ -22,7 +22,7 @@ - + From d48928969d402643a0f085314fdf40690fefd224 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 2 Nov 2022 20:23:05 +0800 Subject: [PATCH 16/38] refactor(Exception): Refactor Exception --- Masa.Framework.sln | 11 -- .../Constants/ErrorCode.cs | 11 ++ ...ldingBlocks.Development.DaprStarter.csproj | 3 +- .../Options/DaprOptions.cs | 39 ++---- .../MasaArgumentException.cs | 30 ++++ ...Authentication.OpenIdConnect.EFCore.csproj | 2 +- .../TestBase.cs | 2 +- .../Masa.Contrib.Data.Mapping.Mapster.csproj | 2 +- .../Masa.Contrib.Data.EFCore.csproj | 2 +- .../Masa.Contrib.Ddd.Domain.csproj | 2 +- ....Development.DaprStarter.AspNetCore.csproj | 2 +- ...asa.Contrib.Development.DaprStarter.csproj | 1 - ...ntrib.Development.DaprStarter.Tests.csproj | 11 +- ...b.Dispatcher.IntegrationEvents.Dapr.csproj | 1 - ....IntegrationEvents.EventLogs.EFCore.csproj | 1 - .../Masa.Contrib.Dispatcher.Events.csproj | 2 +- .../ApplicationBuilderExtensions.cs | 0 .../Extensions/MvcBuilderExtensions.cs | 0 .../Handlers/ExceptionHandlerMiddleware.cs | 8 +- .../Handlers/ExceptionHandlingMiddleware.cs | 0 .../Handlers/GlobalExceptionFilter.cs | 2 + .../Internal/ExceptionHandlerExtensions.cs | 2 +- .../Masa.Contrib.Exceptions.csproj | 4 +- .../Results/DefaultExceptionResult.cs | 0 .../InternalServerErrorObjectResult.cs | 0 .../Results/UserFriendlyExceptionResult.cs | 0 .../Masa.Contrib.Exceptions/_Imports.cs | 5 +- .../Masa.Contrib.Globalization.I18N.csproj | 5 +- ...sa.Contrib.Globalization.I18N.Tests.csproj | 17 +-- ...ib.RulesEngine.MicrosoftRulesEngine.csproj | 2 +- .../Masa.Contrib.Service.MinimalAPIs.csproj | 2 +- .../IMasaExceptionHandler.cs | 11 -- .../Internal/Constant.cs | 11 -- .../Internal/ExceptionExtensions.cs | 20 --- .../Internal/ExceptionHandlerExtensions.cs | 33 ----- .../Internal/HttpResponseExtensions.cs | 26 ---- .../Masa.Utils.Exceptions.csproj | 13 -- .../Masa.Utils.Exceptions/MasaException.cs | 45 ------ .../MasaExceptionContext.cs | 52 ------- .../MasaHttpStatusCode.cs | 9 -- .../Options/MasaExceptionHandlerOptions.cs | 20 --- .../Options/MasaExceptionHandlingOptions.cs | 13 -- .../MasaExceptionLogRelationOptions.cs | 25 ---- src/Utils/Masa.Utils.Exceptions/README.md | 130 ------------------ .../Masa.Utils.Exceptions/README.zh-CN.md | 130 ------------------ .../UserFriendlyException.cs | 30 ---- src/Utils/Masa.Utils.Exceptions/_Imports.cs | 17 --- 47 files changed, 99 insertions(+), 655 deletions(-) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Extensions/ApplicationBuilderExtensions.cs (100%) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Extensions/MvcBuilderExtensions.cs (100%) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Handlers/ExceptionHandlerMiddleware.cs (92%) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Handlers/ExceptionHandlingMiddleware.cs (100%) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Handlers/GlobalExceptionFilter.cs (98%) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Results/DefaultExceptionResult.cs (100%) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Results/InternalServerErrorObjectResult.cs (100%) rename src/{Utils/Masa.Utils.Exceptions => Contrib/Exception/Masa.Contrib.Exceptions}/Results/UserFriendlyExceptionResult.cs (100%) delete mode 100644 src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Internal/Constant.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Internal/HttpResponseExtensions.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Masa.Utils.Exceptions.csproj delete mode 100644 src/Utils/Masa.Utils.Exceptions/MasaException.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/MasaExceptionContext.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/MasaHttpStatusCode.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/README.md delete mode 100644 src/Utils/Masa.Utils.Exceptions/README.zh-CN.md delete mode 100644 src/Utils/Masa.Utils.Exceptions/UserFriendlyException.cs delete mode 100644 src/Utils/Masa.Utils.Exceptions/_Imports.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index f3d420df2..5ff07a29b 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -131,8 +131,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authentication", "Authentic EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Caching.Memory", "src\Utils\Caching\Masa.Utils.Caching.Memory\Masa.Utils.Caching.Memory.csproj", "{015C4181-A8D9-4FA5-89B9-38A37FA9D31D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Exceptions", "src\Utils\Masa.Utils.Exceptions\Masa.Utils.Exceptions.csproj", "{7B0EDB07-D3AE-4077-9A23-35CA6556E791}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Configuration.Json", "src\Utils\Configuration\Masa.Utils.Configuration.Json\Masa.Utils.Configuration.Json.csproj", "{8AB652AF-3957-42F9-8F3E-FAFE56A44BE1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Utils.Data.DataAnnotations", "src\Utils\Data\Masa.Utils.Data.DataAnnotations\Masa.Utils.Data.DataAnnotations.csproj", "{766E3633-7B82-49CC-B012-CAE6264D4628}" @@ -876,14 +874,6 @@ Global {015C4181-A8D9-4FA5-89B9-38A37FA9D31D}.Release|Any CPU.Build.0 = Release|Any CPU {015C4181-A8D9-4FA5-89B9-38A37FA9D31D}.Release|x64.ActiveCfg = Release|Any CPU {015C4181-A8D9-4FA5-89B9-38A37FA9D31D}.Release|x64.Build.0 = Release|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Debug|x64.ActiveCfg = Debug|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Debug|x64.Build.0 = Debug|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Release|Any CPU.Build.0 = Release|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Release|x64.ActiveCfg = Release|Any CPU - {7B0EDB07-D3AE-4077-9A23-35CA6556E791}.Release|x64.Build.0 = Release|Any CPU {8AB652AF-3957-42F9-8F3E-FAFE56A44BE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8AB652AF-3957-42F9-8F3E-FAFE56A44BE1}.Debug|Any CPU.Build.0 = Debug|Any CPU {8AB652AF-3957-42F9-8F3E-FAFE56A44BE1}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2273,7 +2263,6 @@ Global {2D07F9AD-9951-475D-B7C7-980B23FDE9BB} = {5944A182-13B8-4DA6-AEE2-0A01E64A9648} {534346EF-1D11-48DB-9909-700CEC99FF08} = {2D07F9AD-9951-475D-B7C7-980B23FDE9BB} {015C4181-A8D9-4FA5-89B9-38A37FA9D31D} = {AF921AB1-64D1-4478-AB49-192F3EE416FC} - {7B0EDB07-D3AE-4077-9A23-35CA6556E791} = {5944A182-13B8-4DA6-AEE2-0A01E64A9648} {8AB652AF-3957-42F9-8F3E-FAFE56A44BE1} = {56917740-626B-42D5-8BB8-6895F79FB7D2} {766E3633-7B82-49CC-B012-CAE6264D4628} = {706DA866-6226-430F-AB4D-98FEE7B0DDB0} {B7003322-212E-4568-9B61-95DB67CABC3F} = {706DA866-6226-430F-AB4D-98FEE7B0DDB0} diff --git a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs index dd2615644..91aafbcbe 100644 --- a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs +++ b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs @@ -60,5 +60,16 @@ public static class ErrorCode /// public const string ARGUMENT_LESS_THAN_OR_EQUAL = $"{ARGUMENT}0009"; + /// + /// Value does not support {0} + /// + public const string ARGUMENT_NOT_SUPPORTED_SINGLE = $"{ARGUMENT}0010"; + + /// + /// Value does not support {0} or {1}. (Parameter 'value') + /// + public const string ARGUMENT_NOT_SUPPORTED_MULTI = $"{ARGUMENT}0011"; + #endregion + } diff --git a/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Masa.BuildingBlocks.Development.DaprStarter.csproj b/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Masa.BuildingBlocks.Development.DaprStarter.csproj index f20f98800..d09170b61 100644 --- a/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Masa.BuildingBlocks.Development.DaprStarter.csproj +++ b/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Masa.BuildingBlocks.Development.DaprStarter.csproj @@ -7,7 +7,8 @@ - + + diff --git a/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Options/DaprOptions.cs b/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Options/DaprOptions.cs index 92e1b341f..387ed3720 100644 --- a/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Options/DaprOptions.cs +++ b/src/BuildingBlocks/Development/Masa.BuildingBlocks.Development.DaprStarter/Options/DaprOptions.cs @@ -28,10 +28,7 @@ public string AppIdDelimiter get => _appIdDelimiter; set { - if (value == ".") - { - throw new NotSupportedException("AppIdDelimiter is not supported as ."); - } + MasaArgumentException.ThrowIfContain(value, ".", nameof(AppIdDelimiter)); _appIdDelimiter = value; } @@ -49,10 +46,7 @@ public string? AppIdSuffix get => _appIdSuffix; set { - if (value == ".") - { - throw new NotSupportedException("AppIdSuffix is not supported as ."); - } + MasaArgumentException.ThrowIfContain(value, ".", nameof(AppIdSuffix)); _appIdSuffix = value; } @@ -75,10 +69,8 @@ public int? MaxConcurrency get => _maxConcurrency; set { - if (value is <= 0) - { - throw new NotSupportedException($"{nameof(MaxConcurrency)} must be greater than 0 ."); - } + if (value != null) + MasaArgumentException.ThrowIfLessThanOrEqual(value.Value, (ushort)0, nameof(MaxConcurrency)); _maxConcurrency = value; } @@ -95,8 +87,8 @@ public ushort? AppPort get => _appPort; set { - if (value is <= 0) - throw new NotSupportedException($"{nameof(AppPort)} must be greater than 0 ."); + if (value != null) + MasaArgumentException.ThrowIfLessThanOrEqual(value.Value, (ushort)0, nameof(AppPort)); _appPort = value; } @@ -140,8 +132,8 @@ public ushort? DaprGrpcPort get => _daprGrpcPort; set { - if (value is <= 0) - throw new NotSupportedException($"{nameof(DaprGrpcPort)} must be greater than 0 ."); + if (value != null) + MasaArgumentException.ThrowIfLessThanOrEqual(value.Value, (ushort)0, nameof(DaprGrpcPort)); _daprGrpcPort = value; } @@ -158,8 +150,8 @@ public ushort? DaprHttpPort get => _daprHttpPort; set { - if (value is <= 0) - throw new NotSupportedException($"{nameof(DaprHttpPort)} must be greater than 0 ."); + if (value != null) + MasaArgumentException.ThrowIfLessThanOrEqual(value.Value, (ushort)0, nameof(DaprHttpPort)); _daprHttpPort = value; } @@ -220,8 +212,8 @@ public ushort? ProfilePort get => _profilePort; set { - if (value is <= 0) - throw new NotSupportedException($"{nameof(ProfilePort)} must be greater than 0 ."); + if (value != null) + MasaArgumentException.ThrowIfLessThanOrEqual(value.Value, (ushort)0, nameof(ProfilePort)); _profilePort = value; } @@ -245,8 +237,8 @@ public int? DaprMaxRequestSize get => _daprMaxRequestSize; set { - if (value is <= 0) - throw new NotSupportedException($"{nameof(DaprMaxRequestSize)} must be greater than 0 ."); + if (value != null) + MasaArgumentException.ThrowIfLessThanOrEqual(value.Value, (ushort)0, nameof(DaprMaxRequestSize)); _daprMaxRequestSize = value; } @@ -264,8 +256,7 @@ public int HeartBeatInterval get => _heartBeatInterval; set { - if (value < 0) - throw new NotSupportedException($"{nameof(DaprMaxRequestSize)} must be greater than or equal to 0 ."); + MasaArgumentException.ThrowIfLessThanOrEqual(value, (ushort)0, nameof(HeartBeatInterval)); _heartBeatInterval = value; } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs index 6068e45cf..797f30d17 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -119,6 +119,36 @@ public static void ThrowIfOutOfRange(T argument, maxValue); } + public static void ThrowIfContain(string? argument, + string parameter, + [CallerArgumentExpression("argument")] string? paramName = null) + => ThrowIfContain(argument, parameter, StringComparison.OrdinalIgnoreCase, paramName); + + public static void ThrowIfContain(string? argument, + string parameter, + StringComparison stringComparison, + [CallerArgumentExpression("argument")] string? paramName = null) + => ThrowIfContain(argument, new[] { parameter }, stringComparison, parameter); + + public static void ThrowIfContain(string? argument, + IEnumerable parameters, + [CallerArgumentExpression("argument")] string? paramName = null) + => ThrowIfContain(argument, parameters, StringComparison.OrdinalIgnoreCase, paramName); + + public static void ThrowIfContain(string? argument, + IEnumerable parameters, + StringComparison stringComparison, + [CallerArgumentExpression("argument")] string? paramName = null) + { + if (argument != null) + ThrowIf(parameters.Any(parameter => argument.Contains(parameter, stringComparison)), + paramName, + parameters.Count() == 1 ? Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NOT_SUPPORTED_SINGLE : + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NOT_SUPPORTED_MULTI, + parameters + ); + } + public static void ThrowIf(bool condition, string? paramName, string errorCode, params object[] parameters) { if (condition) Throw(paramName, errorCode, parameters); diff --git a/src/Contrib/Authentication/OpenIdConnect/Masa.Contrib.Authentication.OpenIdConnect.EFCore/Masa.Contrib.Authentication.OpenIdConnect.EFCore.csproj b/src/Contrib/Authentication/OpenIdConnect/Masa.Contrib.Authentication.OpenIdConnect.EFCore/Masa.Contrib.Authentication.OpenIdConnect.EFCore.csproj index fd6dac2ce..c00d4e4ae 100644 --- a/src/Contrib/Authentication/OpenIdConnect/Masa.Contrib.Authentication.OpenIdConnect.EFCore/Masa.Contrib.Authentication.OpenIdConnect.EFCore.csproj +++ b/src/Contrib/Authentication/OpenIdConnect/Masa.Contrib.Authentication.OpenIdConnect.EFCore/Masa.Contrib.Authentication.OpenIdConnect.EFCore.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs b/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs index 1c2b1fa39..d82a761b8 100644 --- a/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs +++ b/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs @@ -13,7 +13,7 @@ protected static RedisConfigurationOptions GetConfigurationOptions() { GlobalCacheOptions = new CacheOptions() { - CacheKeyType = CacheKeyType.None + CacheKeyType = CacheKeyType.TypeName } }; redisConfigurationOptions.Servers.Add(new RedisServerOptions()); diff --git a/src/Contrib/Data/Mapping/Masa.Contrib.Data.Mapping.Mapster/Masa.Contrib.Data.Mapping.Mapster.csproj b/src/Contrib/Data/Mapping/Masa.Contrib.Data.Mapping.Mapster/Masa.Contrib.Data.Mapping.Mapster.csproj index a089c9f1c..bf37ed582 100644 --- a/src/Contrib/Data/Mapping/Masa.Contrib.Data.Mapping.Mapster/Masa.Contrib.Data.Mapping.Mapster.csproj +++ b/src/Contrib/Data/Mapping/Masa.Contrib.Data.Mapping.Mapster/Masa.Contrib.Data.Mapping.Mapster.csproj @@ -14,8 +14,8 @@ + - diff --git a/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/Masa.Contrib.Data.EFCore.csproj b/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/Masa.Contrib.Data.EFCore.csproj index b4e6c1d6a..a89182ee0 100644 --- a/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/Masa.Contrib.Data.EFCore.csproj +++ b/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/Masa.Contrib.Data.EFCore.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Contrib/Ddd/Domain/Masa.Contrib.Ddd.Domain/Masa.Contrib.Ddd.Domain.csproj b/src/Contrib/Ddd/Domain/Masa.Contrib.Ddd.Domain/Masa.Contrib.Ddd.Domain.csproj index 0e5827090..e7e6e0a15 100644 --- a/src/Contrib/Ddd/Domain/Masa.Contrib.Ddd.Domain/Masa.Contrib.Ddd.Domain.csproj +++ b/src/Contrib/Ddd/Domain/Masa.Contrib.Ddd.Domain/Masa.Contrib.Ddd.Domain.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Contrib/Development/Masa.Contrib.Development.DaprStarter.AspNetCore/Masa.Contrib.Development.DaprStarter.AspNetCore.csproj b/src/Contrib/Development/Masa.Contrib.Development.DaprStarter.AspNetCore/Masa.Contrib.Development.DaprStarter.AspNetCore.csproj index d8f8a6f19..b570e442a 100644 --- a/src/Contrib/Development/Masa.Contrib.Development.DaprStarter.AspNetCore/Masa.Contrib.Development.DaprStarter.AspNetCore.csproj +++ b/src/Contrib/Development/Masa.Contrib.Development.DaprStarter.AspNetCore/Masa.Contrib.Development.DaprStarter.AspNetCore.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/Contrib/Development/Masa.Contrib.Development.DaprStarter/Masa.Contrib.Development.DaprStarter.csproj b/src/Contrib/Development/Masa.Contrib.Development.DaprStarter/Masa.Contrib.Development.DaprStarter.csproj index 470886adf..737ab2543 100644 --- a/src/Contrib/Development/Masa.Contrib.Development.DaprStarter/Masa.Contrib.Development.DaprStarter.csproj +++ b/src/Contrib/Development/Masa.Contrib.Development.DaprStarter/Masa.Contrib.Development.DaprStarter.csproj @@ -18,7 +18,6 @@ - diff --git a/src/Contrib/Development/Tests/Masa.Contrib.Development.DaprStarter.Tests/Masa.Contrib.Development.DaprStarter.Tests.csproj b/src/Contrib/Development/Tests/Masa.Contrib.Development.DaprStarter.Tests/Masa.Contrib.Development.DaprStarter.Tests.csproj index be70feff1..a7d567ad5 100644 --- a/src/Contrib/Development/Tests/Masa.Contrib.Development.DaprStarter.Tests/Masa.Contrib.Development.DaprStarter.Tests.csproj +++ b/src/Contrib/Development/Tests/Masa.Contrib.Development.DaprStarter.Tests/Masa.Contrib.Development.DaprStarter.Tests.csproj @@ -8,10 +8,11 @@ - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -23,7 +24,7 @@ - + diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.csproj b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.csproj index d93a20e6a..cbcd1d650 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.csproj +++ b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.csproj @@ -12,7 +12,6 @@ - diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore.csproj b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore.csproj index aff15520a..a3b8312d3 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore.csproj +++ b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EFCore.csproj @@ -13,7 +13,6 @@ - diff --git a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Masa.Contrib.Dispatcher.Events.csproj b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Masa.Contrib.Dispatcher.Events.csproj index dff3fedda..93e53fd90 100644 --- a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Masa.Contrib.Dispatcher.Events.csproj +++ b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Masa.Contrib.Dispatcher.Events.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/Utils/Masa.Utils.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs similarity index 100% rename from src/Utils/Masa.Utils.Exceptions/Extensions/ApplicationBuilderExtensions.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs diff --git a/src/Utils/Masa.Utils.Exceptions/Extensions/MvcBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs similarity index 100% rename from src/Utils/Masa.Utils.Exceptions/Extensions/MvcBuilderExtensions.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs diff --git a/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs similarity index 92% rename from src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlerMiddleware.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index ad8587fe2..b2d0ea189 100644 --- a/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -3,6 +3,9 @@ // ReSharper disable once CheckNamespace +using System.Net; +using Microsoft.Extensions.Options; + namespace Microsoft.AspNetCore.Builder; public class ExceptionHandlerMiddleware @@ -39,10 +42,7 @@ public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceP } else { - var masaExceptionHandler = - Masa.Utils.Exceptions.ExceptionHandlerExtensions.GetMasaExceptionHandler( - serviceProvider, - _options.MasaExceptionHandlerType); + var masaExceptionHandler = serviceProvider.GetMasaExceptionHandler(_options.MasaExceptionHandlerType); masaExceptionHandler?.OnException(masaExceptionContext); } diff --git a/src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlingMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlingMiddleware.cs similarity index 100% rename from src/Utils/Masa.Utils.Exceptions/Handlers/ExceptionHandlingMiddleware.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlingMiddleware.cs diff --git a/src/Utils/Masa.Utils.Exceptions/Handlers/GlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/GlobalExceptionFilter.cs similarity index 98% rename from src/Utils/Masa.Utils.Exceptions/Handlers/GlobalExceptionFilter.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/GlobalExceptionFilter.cs index 88f077c83..4a7424f70 100644 --- a/src/Utils/Masa.Utils.Exceptions/Handlers/GlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/GlobalExceptionFilter.cs @@ -3,6 +3,8 @@ // ReSharper disable once CheckNamespace +using Microsoft.Extensions.Options; + namespace Microsoft.AspNetCore.Mvc.Filters; /// diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs index c611cd0a4..668dd3f13 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs @@ -5,7 +5,7 @@ namespace Masa.Contrib.Exceptions.Internal; internal static class ExceptionHandlerExtensions { - public static IMasaExceptionHandler? GetMasaExceptionHandler(IServiceProvider serviceProvider, Type? masaExceptionHandlerType) + public static IMasaExceptionHandler? GetMasaExceptionHandler(this IServiceProvider serviceProvider, Type? masaExceptionHandlerType) { var exceptionHandler = serviceProvider.GetService(); if (exceptionHandler != null) diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj index 349dcb244..281f369a9 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/src/Utils/Masa.Utils.Exceptions/Results/DefaultExceptionResult.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs similarity index 100% rename from src/Utils/Masa.Utils.Exceptions/Results/DefaultExceptionResult.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs diff --git a/src/Utils/Masa.Utils.Exceptions/Results/InternalServerErrorObjectResult.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/InternalServerErrorObjectResult.cs similarity index 100% rename from src/Utils/Masa.Utils.Exceptions/Results/InternalServerErrorObjectResult.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Results/InternalServerErrorObjectResult.cs diff --git a/src/Utils/Masa.Utils.Exceptions/Results/UserFriendlyExceptionResult.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/UserFriendlyExceptionResult.cs similarity index 100% rename from src/Utils/Masa.Utils.Exceptions/Results/UserFriendlyExceptionResult.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Results/UserFriendlyExceptionResult.cs diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs index 7dbbc7168..36d5bc563 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs @@ -1,10 +1,13 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.Contrib.Exceptions; global using Microsoft.AspNetCore.Http; global using Microsoft.Extensions.Logging; global using System.Text; global using System.Reflection; global using Microsoft.Extensions.DependencyInjection; global using Masa.Contrib.Exceptions.Internal; +global using System.Net; +global using Microsoft.Extensions.Options; +global using Microsoft.AspNetCore.Mvc; +global using Microsoft.AspNetCore.Mvc.Filters; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index 07afb0cda..77d18a4a3 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -10,7 +10,10 @@ - + + + + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj index c9e336410..a4020544a 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj @@ -8,6 +8,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -16,26 +17,26 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + - - + + - + Always - + diff --git a/src/Contrib/RulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine.csproj b/src/Contrib/RulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine.csproj index 73d670eb7..644525a64 100644 --- a/src/Contrib/RulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine.csproj +++ b/src/Contrib/RulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine/Masa.Contrib.RulesEngine.MicrosoftRulesEngine.csproj @@ -7,8 +7,8 @@ + - diff --git a/src/Contrib/Service/Masa.Contrib.Service.MinimalAPIs/Masa.Contrib.Service.MinimalAPIs.csproj b/src/Contrib/Service/Masa.Contrib.Service.MinimalAPIs/Masa.Contrib.Service.MinimalAPIs.csproj index 0148a036b..ca34630c7 100644 --- a/src/Contrib/Service/Masa.Contrib.Service.MinimalAPIs/Masa.Contrib.Service.MinimalAPIs.csproj +++ b/src/Contrib/Service/Masa.Contrib.Service.MinimalAPIs/Masa.Contrib.Service.MinimalAPIs.csproj @@ -11,10 +11,10 @@ + - diff --git a/src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs b/src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs deleted file mode 100644 index da293c371..000000000 --- a/src/Utils/Masa.Utils.Exceptions/IMasaExceptionHandler.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -public interface IMasaExceptionHandler -{ - void OnException(MasaExceptionContext context); -} diff --git a/src/Utils/Masa.Utils.Exceptions/Internal/Constant.cs b/src/Utils/Masa.Utils.Exceptions/Internal/Constant.cs deleted file mode 100644 index 365fdc907..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Internal/Constant.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Utils.Exceptions.Internal; - -internal static class Constant -{ - public const string DEFAULT_HTTP_CONTENT_TYPE = "text/plain; charset=utf-8"; - - public const string DEFAULT_EXCEPTION_MESSAGE = "An error occur in masa framework."; -} diff --git a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs b/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs deleted file mode 100644 index 4ead86360..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -internal static class ExceptionExtensions -{ - public static void WriteLog( - this ILogger logger, - Exception exception, - LogLevel defaultLogLevel, - MasaExceptionLogRelationOptions logRelationOptions, - string? message = null) - { - var logLevel = logRelationOptions.GetLogLevel(exception, defaultLogLevel); - logger.Log(logLevel, exception, message ?? exception.Message); - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs b/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs deleted file mode 100644 index ecd3b1a65..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Internal/ExceptionHandlerExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Masa.Utils.Exceptions; - -internal static class ExceptionHandlerExtensions -{ - public static IMasaExceptionHandler? GetMasaExceptionHandler(IServiceProvider serviceProvider, Type? masaExceptionHandlerType) - { - var exceptionHandler = serviceProvider.GetService(); - if (exceptionHandler != null) - return exceptionHandler; - - if (masaExceptionHandlerType == null) - return null; - - var constructor = masaExceptionHandlerType.GetConstructors(BindingFlags.Instance | BindingFlags.Public) - .MaxBy(c => c.GetParameters().Length); - List parameters = new(); - if (constructor != null) - { - foreach (var parameterInfo in constructor.GetParameters()) - parameters.Add(serviceProvider.GetService(parameterInfo.ParameterType)); - } - var instance = Activator.CreateInstance(masaExceptionHandlerType, parameters.ToArray()); - if (instance != null) - return instance as IMasaExceptionHandler; - - return null; - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/Internal/HttpResponseExtensions.cs b/src/Utils/Masa.Utils.Exceptions/Internal/HttpResponseExtensions.cs deleted file mode 100644 index 8909aab1c..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Internal/HttpResponseExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Utils.Exceptions.Internal; - -internal static class HttpResponseExtensions -{ - /// - /// Write response with text/plain - /// - /// - /// - /// - /// - /// - public static async Task WriteTextAsync( - this HttpResponse httpResponse, - int statusCode, - string text, - string contentType = "text/plain; charset=utf-8") - { - httpResponse.StatusCode = statusCode; - httpResponse.ContentType = contentType; - await httpResponse.WriteAsync(text, Encoding.UTF8); - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/Masa.Utils.Exceptions.csproj b/src/Utils/Masa.Utils.Exceptions/Masa.Utils.Exceptions.csproj deleted file mode 100644 index b73295abb..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Masa.Utils.Exceptions.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - \ No newline at end of file diff --git a/src/Utils/Masa.Utils.Exceptions/MasaException.cs b/src/Utils/Masa.Utils.Exceptions/MasaException.cs deleted file mode 100644 index 39b501c35..000000000 --- a/src/Utils/Masa.Utils.Exceptions/MasaException.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -[Serializable] -public class MasaException : Exception -{ - public string? ErrorCode { get; private set; } - - public object[] Parameters { get; private set; } - - public MasaException() - { - } - - public MasaException(string message) - : base(message) - { - } - - public MasaException(string errorCode, params object[] parameters) - : this(null, errorCode, parameters) - { - } - - public MasaException(Exception? innerException, string errorCode, params object[] parameters) - : base(null, innerException) - { - ErrorCode = errorCode; - Parameters = parameters; - } - - public MasaException(string message, Exception? innerException) - : base(message, innerException) - { - } - - public MasaException(SerializationInfo serializationInfo, StreamingContext context) - : base(serializationInfo, context) - { - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/MasaExceptionContext.cs b/src/Utils/Masa.Utils.Exceptions/MasaExceptionContext.cs deleted file mode 100644 index cd4735f09..000000000 --- a/src/Utils/Masa.Utils.Exceptions/MasaExceptionContext.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -public class MasaExceptionContext -{ - public IServiceProvider ServiceProvider { get; set; } - - public Exception Exception { get; set; } - - public HttpContext HttpContext { get; } - - public bool ExceptionHandled { get; set; } - - /// - /// Http status code - /// - public int StatusCode { get; set; } - - /// - /// Error code to provide support for subsequent I18n - /// - public string? ErrorCode { get; set; } - - public string? Message { get; set; } - - public string ContentType { get; set; } - - internal MasaExceptionContext(Exception exception, HttpContext httpContext, IServiceProvider serviceProvider) - { - Exception = exception; - HttpContext = httpContext; - StatusCode = (int)MasaHttpStatusCode.UserFriendlyException; - ExceptionHandled = false; - ContentType = Constant.DEFAULT_HTTP_CONTENT_TYPE; - ServiceProvider = serviceProvider; - } - - public void ToResult( - string message, - int statusCode = (int)MasaHttpStatusCode.UserFriendlyException, - string contentType = Constant.DEFAULT_HTTP_CONTENT_TYPE) - { - Message = message; - StatusCode = statusCode; - ExceptionHandled = true; - ContentType = contentType; - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/MasaHttpStatusCode.cs b/src/Utils/Masa.Utils.Exceptions/MasaHttpStatusCode.cs deleted file mode 100644 index 9570e1afc..000000000 --- a/src/Utils/Masa.Utils.Exceptions/MasaHttpStatusCode.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Utils.Exceptions; - -public enum MasaHttpStatusCode -{ - UserFriendlyException = 299 -} diff --git a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs deleted file mode 100644 index 330c88bb1..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlerOptions.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -public class MasaExceptionHandlerOptions -{ - public bool CatchAllException { get; set; } = true; - - public Action? ExceptionHandler { get; set; } - - internal Type? MasaExceptionHandlerType { get; private set; } - - public void UseExceptionHanlder() where TExceptionHanlder : IMasaExceptionHandler - { - MasaExceptionHandlerType = typeof(TExceptionHanlder); - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs deleted file mode 100644 index f923670f3..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionHandlingOptions.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -public class MasaExceptionHandlingOptions -{ - public bool CatchAllException { get; set; } = true; - - public Func? CustomExceptionHandler { get; set; } -} diff --git a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs b/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs deleted file mode 100644 index 1824bee93..000000000 --- a/src/Utils/Masa.Utils.Exceptions/Options/MasaExceptionLogRelationOptions.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -public class MasaExceptionLogRelationOptions -{ - internal Dictionary Mappings { get; } = new(); - - public MasaExceptionLogRelationOptions MapLogLevel(LogLevel logLevel) where TException : Exception - { - Mappings[typeof(TException)] = logLevel; - return this; - } - - internal LogLevel GetLogLevel(Exception exception, LogLevel defaultLogLevel) - { - if (!Mappings.TryGetValue(exception.GetType(), out var logLevel)) - logLevel = defaultLogLevel; - - return logLevel; - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/README.md b/src/Utils/Masa.Utils.Exceptions/README.md deleted file mode 100644 index e03c24b21..000000000 --- a/src/Utils/Masa.Utils.Exceptions/README.md +++ /dev/null @@ -1,130 +0,0 @@ -[中](README.zh-CN.md) | EN - -## Masa.Utils.Exceptions - -Provides a model for handling web application exceptions - -* Support custom handling exceptions for handling exceptions not provided by Masa -* Take over the `UserFriendlyException` exception and respond with a status code of 299 and return a friendly error message -* Handle all exceptions by default, and output `An error occur in masa framework` externally - -Example: - -``` powershell -Install-Package Masa.Utils.Exceptions -``` - -1. Modify `Program.cs` - -``` C# -app.UseMasaExceptionHandler(); -``` - -2. How to use? - -``` C# -app.MapGet("/Test", () -{ - throw new UserFriendlyException("This method is deprecated"); -} -``` - -3. Error response message, where Http status code is 299 - -``` js -axios - .get('/Test') - .then(response => { - if (response.status === 299) { - alert(response.data); - } - }) -``` - -## How to customize exception handling? - -1. By specifying `ExceptionHandler` - - ```` C# - app.UseMasaExceptionHandler(option => - { - option.CatchAllException = true;//Whether to catch all exceptions, the default is true, the default output of caught exceptions: An error occur in masa framework - - // Custom handling exceptions, similar to ExceptionFilter, can handle exception information according to the exception type, and output the response result through the ToResult method - option.ExceptionHandler = context => - { - if (context.Exception is ArgumentNullException argumentNullException) - { - context.ExceptionHandled = true; - context.Message = "Parameter cannot be empty"; - // or abbreviated as: context.ToResult("Parameter cannot be empty"); - } - }; - }); - ```` - -2. Implement the `IExceptionHandler` interface and register it with the service - - ```` C# - public class ExceptionHandler : IMasaExceptionHandler - { - private readonly ILogger _logger; - - public ExceptionHandler(ILogger logger) - { - _logger = logger; - } - - public void OnException(MasaExceptionContext context) - { - if (context.Exception is ArgumentNullException) - { - _logger.LogWarning(context.Message); - context.ToResult(context.Exception.Message); - } - } - } - builder.Services.AddSingleton(); - - app.UseMasaExceptionHandler(); - ```` - -3. Implement the `IExceptionHandler` interface and specify the use of Handler - - ```` C# - public class ExceptionHandler : IMasaExceptionHandler - { - private readonly ILogger _logger; - - public ExceptionHandler(ILogger logger) - { - _logger = logger; - } - - public void OnException(MasaExceptionContext context) - { - if (context.Exception is ArgumentNullException) - { - _logger.LogWarning(context.Message); - context.ToResult(context.Exception.Message); - } - } - } - app.UseMasaExceptionHandler(option => - { - option.UseExceptionHanlder(); - }); - ```` - -## Common problem - -The default log level of `UserFriendlyException` is `Information`, other types of exceptions are `Error` - -1. How to modify the log level of UserFriendlyException? - - ```` C# - builder.Services.Configure(options => - { - options.MapLogLevel(LogLevel.None); - }); - ```` \ No newline at end of file diff --git a/src/Utils/Masa.Utils.Exceptions/README.zh-CN.md b/src/Utils/Masa.Utils.Exceptions/README.zh-CN.md deleted file mode 100644 index cc93bb3ac..000000000 --- a/src/Utils/Masa.Utils.Exceptions/README.zh-CN.md +++ /dev/null @@ -1,130 +0,0 @@ -中 | [EN](README.md) - -## Masa.Utils.Exceptions - -提供了用于处理Web应用程序异常的模型 - -* 支持自定义处理异常,用于处理非Masa提供的异常 -* 接管`UserFriendlyException`异常,并响应状态码为299,返回友好的错误信息 -* 默认处理所有异常,并对外输出`An error occur in masa framework` - -用例: - -``` powershell -Install-Package Masa.Utils.Exceptions -``` - -1. 修改`Program.cs` - -``` C# -app.UseMasaExceptionHandler(); -``` - -2. 如何使用? - -``` C# -app.MapGet("/Test", () -{ - throw new UserFriendlyException("This method is deprecated"); -} -``` - -3. 错误响应消息,其中Http状态码为299 - -``` js -axios - .get('/Test') - .then(response => { - if (response.status === 299) { - alert(response.data); - } - }) -``` - -## 如何自定义异常处理? - -1. 通过指定`ExceptionHandler` - - ``` C# - app.UseMasaExceptionHandler(option => - { - option.CatchAllException = true;//是否捕获所有异常,默认为true,捕获到的异常默认输出:An error occur in masa framework - - // 自定义处理异常,与ExceptionFilter类似,可根据异常类型处理异常信息,并通过ToResult方法输出响应结果 - option.ExceptionHandler = context => - { - if (context.Exception is ArgumentNullException argumentNullException) - { - context.ExceptionHandled = true; - context.Message = "参数不能为空"; - // 或者简写为context.ToResult("参数不能为空"); - } - }; - }); - ``` - -2. 实现`IExceptionHandler`接口,并注册到服务中 - - ``` C# - public class ExceptionHandler : IMasaExceptionHandler - { - private readonly ILogger _logger; - - public ExceptionHandler(ILogger logger) - { - _logger = logger; - } - - public void OnException(MasaExceptionContext context) - { - if (context.Exception is ArgumentNullException) - { - _logger.LogWarning(context.Message); - context.ToResult(context.Exception.Message); - } - } - } - builder.Services.AddSingleton(); - - app.UseMasaExceptionHandler(); - ``` - -3. 实现`IExceptionHandler`接口,并指定使用Handler - - ``` C# - public class ExceptionHandler : IMasaExceptionHandler - { - private readonly ILogger _logger; - - public ExceptionHandler(ILogger logger) - { - _logger = logger; - } - - public void OnException(MasaExceptionContext context) - { - if (context.Exception is ArgumentNullException) - { - _logger.LogWarning(context.Message); - context.ToResult(context.Exception.Message); - } - } - } - app.UseMasaExceptionHandler(option => - { - option.UseExceptionHanlder(); - }); - ``` - -## 常见问题 - -默认`UserFriendlyException`的日志等级为`Information`, 其它类型异常为`Error` - -1. 如何修改UserFriendlyException的日志等级? - -``` C# -builder.Services.Configure(options => -{ - options.MapLogLevel(LogLevel.None); -}); -``` \ No newline at end of file diff --git a/src/Utils/Masa.Utils.Exceptions/UserFriendlyException.cs b/src/Utils/Masa.Utils.Exceptions/UserFriendlyException.cs deleted file mode 100644 index dedf96fc8..000000000 --- a/src/Utils/Masa.Utils.Exceptions/UserFriendlyException.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -[Serializable] -public class UserFriendlyException : MasaException -{ - public UserFriendlyException(string message) - : base(message) - { - } - - public UserFriendlyException(string message, Exception? innerException) - : base(message, innerException) - { - } - - public UserFriendlyException(string errorCode, params object[] parameters) - : base(errorCode, parameters) - { - } - - public UserFriendlyException(Exception? innerException, string errorCode, params object[] parameters) - : base(innerException, errorCode, parameters) - { - } -} diff --git a/src/Utils/Masa.Utils.Exceptions/_Imports.cs b/src/Utils/Masa.Utils.Exceptions/_Imports.cs deleted file mode 100644 index e2062f7ee..000000000 --- a/src/Utils/Masa.Utils.Exceptions/_Imports.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -global using Masa.Utils.Exceptions; -global using Masa.Utils.Exceptions.Internal; -global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Mvc.Filters; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Logging; -global using Microsoft.Extensions.Options; -global using System.Diagnostics.CodeAnalysis; -global using System.Net; -global using System.Reflection; -global using System.Runtime.CompilerServices; -global using System.Runtime.Serialization; -global using System.Text; From 53c9b15ad95edb6a2d17b98bcd20b33e1c9316f7 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 3 Nov 2022 18:43:08 +0800 Subject: [PATCH 17/38] feat: Support Exception --- Masa.Framework.sln | 22 ++++++ .../Constants/ErrorCode.cs | 76 ++++++++++++++++--- .../Masa.BuildingBlocks.Data.csproj | 1 + ...asa.BuildingBlocks.Exceptions.Tests.csproj | 21 +++++ .../MasaArgumentExceptionTest.cs | 24 ++++++ .../_Imports.cs | 7 ++ .../Masa.BuildingBlocks.Exceptions.csproj | 7 ++ .../MasaArgumentException.cs | 32 +++++--- .../MasaException.cs | 14 +++- .../UserFriendlyException.cs | 8 +- .../_Imports.cs | 1 + .../MasaConfigurationExtensions.cs | 22 +++--- .../Masa.Contrib.Data.EFCore/MasaDbContext.cs | 6 +- .../Options/DispatcherOptions.cs | 3 +- .../Options/DispatcherOptions.cs | 3 +- .../Masa.Contrib.Exceptions.Zh-CN.csproj | 20 +++++ .../Resources/i18n/framework/zh-CN.json | 15 ++++ .../ApplicationBuilderExtensions.cs | 41 +--------- .../Extensions/MvcBuilderExtensions.cs | 2 +- .../Handlers/ExceptionHandlerMiddleware.cs | 26 +++---- .../Handlers/ExceptionHandlingMiddleware.cs | 58 -------------- ...nFilter.cs => MvcGlobalExceptionFilter.cs} | 41 ++++++---- .../Internal/Constant.cs | 2 +- .../Internal/ExceptionExtensions.cs | 55 +++++++++++--- .../Internal/LoggerExtensions.cs | 30 ++++++++ ...nsions.cs => ServiceProviderExtensions.cs} | 2 +- .../Masa.Contrib.Exceptions.csproj | 1 + .../Options/MasaExceptionHandlerOptions.cs | 4 +- .../Options/MasaExceptionHandlingOptions.cs | 13 ---- .../Results/DefaultExceptionResult.cs | 6 +- .../Masa.Contrib.Exceptions/_Imports.cs | 2 + .../Extensions/ServiceCollectionExtensions.cs | 10 ++- .../Internal/Constant.cs | 2 + .../JsonConfigurationUtils.cs | 4 +- .../DefaultStorageClient.cs | 2 +- .../Internal/ObjectStorageExtensions.cs | 5 +- .../ServiceCollectionExtensions.cs | 6 +- .../Utils/AttributeUtils.cs | 32 ++++++++ .../AttributeTest.cs | 21 +++++ 39 files changed, 435 insertions(+), 212 deletions(-) create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/Masa.BuildingBlocks.Exceptions.Tests.csproj create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/_Imports.cs create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Resources/i18n/framework/zh-CN.json delete mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlingMiddleware.cs rename src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/{GlobalExceptionFilter.cs => MvcGlobalExceptionFilter.cs} (55%) create mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs rename src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/{ExceptionHandlerExtensions.cs => ServiceProviderExtensions.cs} (96%) delete mode 100644 src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/{Json => Internal}/JsonConfigurationUtils.cs (95%) create mode 100644 src/Utils/Extensions/Masa.Utils.Extensions.DotNet/Utils/AttributeUtils.cs create mode 100644 src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/AttributeTest.cs diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 5ff07a29b..c238b0d49 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -626,6 +626,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Excepti EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Exceptions", "src\Contrib\Exception\Masa.Contrib.Exceptions\Masa.Contrib.Exceptions.csproj", "{C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Exceptions.Zh-CN", "src\Contrib\Exception\Masa.Contrib.Exceptions.Zh-CN\Masa.Contrib.Exceptions.Zh-CN.csproj", "{AC032E31-83E5-4A50-A4A6-F18E67BA9475}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Exceptions.Tests", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions.Tests\Masa.BuildingBlocks.Exceptions.Tests.csproj", "{921DCAAC-3146-4EDB-891C-D76089E4A451}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2202,6 +2206,22 @@ Global {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|Any CPU.Build.0 = Release|Any CPU {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|x64.ActiveCfg = Release|Any CPU {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|x64.Build.0 = Release|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|x64.Build.0 = Debug|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|Any CPU.Build.0 = Release|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|x64.ActiveCfg = Release|Any CPU + {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|x64.Build.0 = Release|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Debug|Any CPU.Build.0 = Debug|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Debug|x64.ActiveCfg = Debug|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Debug|x64.Build.0 = Debug|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Release|Any CPU.ActiveCfg = Release|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Release|Any CPU.Build.0 = Release|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Release|x64.ActiveCfg = Release|Any CPU + {921DCAAC-3146-4EDB-891C-D76089E4A451}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2509,6 +2529,8 @@ Global {F17FFB29-A622-4430-B2EA-E9FF20E68122} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} {145400E0-7AC3-4D7B-88D1-F17847E4FA6D} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48} = {F17FFB29-A622-4430-B2EA-E9FF20E68122} + {AC032E31-83E5-4A50-A4A6-F18E67BA9475} = {F17FFB29-A622-4430-B2EA-E9FF20E68122} + {921DCAAC-3146-4EDB-891C-D76089E4A451} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs index 91aafbcbe..1ed056ddd 100644 --- a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs +++ b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs @@ -5,71 +5,127 @@ namespace Masa.BuildingBlocks.Data.Constants; public static class ErrorCode { - private const string FRAMEWORK = "MF"; + public const string FRAMEWORK_PREFIX = "MF"; #region Type - private const string ARGUMENT = $"{FRAMEWORK}ARG"; + /// + /// Parameter error + /// + private const string ARGUMENT = $"{FRAMEWORK_PREFIX}ARG"; + + /// + /// Internal service error + /// + private const string InternalServer = $"{FRAMEWORK_PREFIX}Ser"; #endregion #region Argument /// - /// + /// Value Error. (Parameter 'value') /// + [Description("Value Error. (Parameter '{0}')")] public const string ARGUMENT_ERROR = $"{ARGUMENT}0001"; /// /// Value cannot be null. (Parameter 'value') /// + [Description("Value cannot be null. (Parameter '{0}')")] public const string ARGUMENT_NULL = $"{ARGUMENT}0002"; /// /// Value cannot be null and empty . (Parameter 'value') /// + [Description("Value cannot be null and empty. (Parameter '{0}')")] public const string ARGUMENT_NULL_OR_EMPTY = $"{ARGUMENT}0003"; /// /// Value cannot be null and WhiteSpace . (Parameter 'value') /// + [Description("Value cannot be null and WhiteSpace . (Parameter '{0}')")] public const string ARGUMENT_NULL_OR_WHITE_SPACE = $"{ARGUMENT}0004"; /// - /// Value must be between {0}-{1} . (Parameter 'value') + /// Value must be between {1}-{2} . (Parameter 'value') /// + [Description("Value must be between {1}-{2} . (Parameter '{0}')")] public const string ARGUMENT_OUT_OF_RANGE = $"{ARGUMENT}0005"; /// - /// Value must be greater than {0} . (Parameter 'value') + /// Value must be greater than {1} . (Parameter 'value') /// + [Description("Value must be greater than {1} . (Parameter '{0}')")] public const string ARGUMENT_GREATER_THAN = $"{ARGUMENT}0006"; /// - /// Value must be greater than or equal {0} . (Parameter 'value') + /// Value must be greater than or equal {1} . (Parameter 'value') /// + [Description("Value must be greater than or equal {1} . (Parameter '{0}')")] public const string ARGUMENT_GREATER_THAN_OR_EQUAL = $"{ARGUMENT}0007"; /// - /// Value must be less than {0} . (Parameter 'value') + /// Value must be less than {1} . (Parameter 'value') /// + [Description("Value must be less than {1} . (Parameter '{0}')")] public const string ARGUMENT_LESS_THAN = $"{ARGUMENT}0008"; /// - /// Value must be less than or equal {0} . (Parameter 'value') + /// Value must be less than or equal {1} . (Parameter 'value') /// + [Description("Value must be less than or equal {1} . (Parameter '{0}')")] public const string ARGUMENT_LESS_THAN_OR_EQUAL = $"{ARGUMENT}0009"; /// - /// Value does not support {0} + /// Value cannot contain {1}. (Parameter 'value') /// + [Description("Value cannot contain {1}. (Parameter '{0}')")] public const string ARGUMENT_NOT_SUPPORTED_SINGLE = $"{ARGUMENT}0010"; /// - /// Value does not support {0} or {1}. (Parameter 'value') + /// Value cannot contain {1} or {2}. (Parameter 'value') /// + [Description("Value cannot contain {1} or {2}. (Parameter '{0}')")] public const string ARGUMENT_NOT_SUPPORTED_MULTI = $"{ARGUMENT}0011"; + /// + /// Value cannot be null or empty collection. (Parameter 'value') + /// + [Description("Value cannot be null or empty collection. (Parameter '{0}')")] + public const string ARGUMENT_NULL_OR_EMPTY_COLLECTION = $"{ARGUMENT}0012"; + + #endregion + + #region Other + + /// + /// Internal service error + /// + [Description("Internal service error")] + public const string INTERNAL_SERVER_ERROR = $"{InternalServer}0001"; + #endregion + private static Dictionary ErrorCodeMessageDictionary = new(); + + static ErrorCode() + { + var classType = typeof(ErrorCode); + var fields = classType.GetFields(BindingFlags.Static | BindingFlags.Public); + foreach (var field in fields) + { + var errorMessage = AttributeUtils.GetDescriptionByField(field); + + ErrorCodeMessageDictionary.Add(field.GetRawConstantValue()!.ToString(), errorMessage); + } + } + + public static string? GetErrorMessage(string errorCode) + { + if (ErrorCodeMessageDictionary.TryGetValue(errorCode, out string? errorMessage)) + return errorMessage; + + return null; + } } diff --git a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Masa.BuildingBlocks.Data.csproj b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Masa.BuildingBlocks.Data.csproj index ff0c10660..7bcbe02ba 100644 --- a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Masa.BuildingBlocks.Data.csproj +++ b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Masa.BuildingBlocks.Data.csproj @@ -11,6 +11,7 @@ + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/Masa.BuildingBlocks.Exceptions.Tests.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/Masa.BuildingBlocks.Exceptions.Tests.csproj new file mode 100644 index 000000000..da55be1b8 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/Masa.BuildingBlocks.Exceptions.Tests.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + enable + false + + + + + + + + + + + + + + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs new file mode 100644 index 000000000..5b5e299d8 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs @@ -0,0 +1,24 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Exceptions.Tests; + +[TestClass] +public class MasaArgumentExceptionTest +{ + [TestMethod] + public void TestThrowIfNull() + { + object? str = null; + + try + { + MasaArgumentException.ThrowIfNull(str); + } + catch (MasaArgumentException ex) + { + Assert.AreEqual(Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL, ex.ErrorCode); + Assert.AreEqual("Value cannot be null. (Parameter '{0}')", ex.ErrorMessage); + } + } +} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/_Imports.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/_Imports.cs new file mode 100644 index 000000000..fb23b4d18 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/_Imports.cs @@ -0,0 +1,7 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using System.Diagnostics.CodeAnalysis; +global using System.Runtime.Serialization; +global using System.Runtime.CompilerServices; +global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj index b3d41f5ba..78fb7d643 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -7,7 +7,14 @@ + + + + C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.8\Microsoft.Extensions.Logging.Abstractions.dll + + + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs index 797f30d17..646a0e94a 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -21,18 +21,18 @@ public MasaArgumentException(string message, string paramName) } public MasaArgumentException(string paramName, params object[] parameters) - : this(paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_ERROR, parameters) + : this(paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_ERROR, "", parameters) { } - public MasaArgumentException(string? paramName, string errorCode, params object[] parameters) - : this((Exception?)null, errorCode, parameters) + public MasaArgumentException(string? paramName, string errorCode, string? errorMessage, params object[] parameters) + : this((Exception?)null, errorCode, errorMessage, parameters) { ParamName = paramName; } - public MasaArgumentException(Exception? innerException, string errorCode, params object[] parameters) - : base(innerException, errorCode, parameters) + public MasaArgumentException(Exception? innerException, string errorCode, string? errorMessage, params object[] parameters) + : base(innerException, errorCode, errorMessage, parameters) { } @@ -46,6 +46,15 @@ public MasaArgumentException(SerializationInfo serializationInfo, StreamingConte { } + public static void ThrowIfNullOrEmptyCollection(IEnumerable? arguments, + [CallerArgumentExpression("arguments")] + string? paramName = null) + { + ThrowIf(arguments is null || !arguments.Any(), + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_EMPTY_COLLECTION); + } + public static void ThrowIfNull(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) { ThrowIf(argument is null, @@ -62,7 +71,7 @@ public static void ThrowIfNullOrEmpty(object? argument, [CallerArgumentExpressio public static void ThrowIfNullOrWhiteSpace(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) { - ThrowIf(argument is null, + ThrowIf(string.IsNullOrWhiteSpace(argument?.ToString()), paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_WHITE_SPACE); } @@ -151,10 +160,15 @@ public static void ThrowIfContain(string? argument, public static void ThrowIf(bool condition, string? paramName, string errorCode, params object[] parameters) { - if (condition) Throw(paramName, errorCode, parameters); + if (condition) Throw(paramName, errorCode, Masa.BuildingBlocks.Data.Constants.ErrorCode.GetErrorMessage(errorCode), parameters); + } + + public static void ThrowIf(bool condition, string? paramName, string errorCode, string? errorMessage, params object[] parameters) + { + if (condition) Throw(paramName, errorCode, errorMessage, parameters); } [DoesNotReturn] - private static void Throw(string? paramName, string errorCode, params object[] parameters) => - throw new MasaArgumentException(paramName, errorCode, parameters); + private static void Throw(string? paramName, string errorCode, string? errorMessage, params object[] parameters) => + throw new MasaArgumentException(paramName, errorCode, errorMessage, parameters); } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index 39b501c35..402654afa 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -8,8 +8,15 @@ namespace System; [Serializable] public class MasaException : Exception { + public virtual LogLevel? LogLevel { get; set; } + public string? ErrorCode { get; private set; } + /// + /// Provides error message that I18n is not used + /// + public string? ErrorMessage { get; set; } + public object[] Parameters { get; private set; } public MasaException() @@ -21,15 +28,16 @@ public MasaException(string message) { } - public MasaException(string errorCode, params object[] parameters) - : this(null, errorCode, parameters) + public MasaException(string errorCode, string? errorMessage, params object[] parameters) + : this(null, errorCode, errorMessage, parameters) { } - public MasaException(Exception? innerException, string errorCode, params object[] parameters) + public MasaException(Exception? innerException, string errorCode, string? errorMessage, params object[] parameters) : base(null, innerException) { ErrorCode = errorCode; + ErrorMessage = errorMessage; Parameters = parameters; } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs index dedf96fc8..900f50333 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs @@ -18,13 +18,13 @@ public UserFriendlyException(string message, Exception? innerException) { } - public UserFriendlyException(string errorCode, params object[] parameters) - : base(errorCode, parameters) + public UserFriendlyException(string errorCode, string errorMessage, params object[] parameters) + : base(errorCode, errorMessage, parameters) { } - public UserFriendlyException(Exception? innerException, string errorCode, params object[] parameters) - : base(innerException, errorCode, parameters) + public UserFriendlyException(Exception? innerException, string errorCode, string errorMessage, params object[] parameters) + : base(innerException, errorCode, errorMessage, parameters) { } } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs index fa282e19c..108ae447d 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Microsoft.Extensions.Logging; global using System.Diagnostics.CodeAnalysis; global using System.Runtime.Serialization; global using System.Runtime.CompilerServices; diff --git a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs index 1232af425..383e90b5c 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Masa.Contrib.Configuration.ConfigurationApi.Dcc/MasaConfigurationExtensions.cs @@ -180,19 +180,21 @@ private static IDistributedCacheClient GetDistributedCacheClient(this IServicePr private static void CheckDccConfigurationOptions(DccConfigurationOptions dccOptions) { - if (string.IsNullOrEmpty(dccOptions.ManageServiceAddress)) - throw new ArgumentNullException(nameof(dccOptions), "ManageServiceAddress cannot be empty"); + MasaArgumentException.ThrowIfNullOrWhiteSpace(dccOptions.ManageServiceAddress); - if (!dccOptions.RedisOptions.Servers.Any()) - throw new ArgumentException("The Redis configuration cannot be empty", nameof(dccOptions)); + MasaArgumentException.ThrowIfNullOrEmptyCollection(dccOptions.RedisOptions.Servers, nameof(dccOptions.RedisOptions)); - if (dccOptions.RedisOptions.Servers.Any(service => string.IsNullOrEmpty(service.Host) || service.Port <= 0)) - throw new ArgumentException( - "The Redis server address cannot be empty, and the Redis port must be grather than 0", - nameof(dccOptions)); + dccOptions.RedisOptions.Servers.ForEach(redisServerOption => + { + MasaArgumentException.ThrowIfNullOrWhiteSpace(redisServerOption.Host, "Redis Host"); + + MasaArgumentException.ThrowIfLessThanOrEqual(redisServerOption.Port, 0, "Redis Port"); + }); - if (dccOptions.ExpandSections.Any(dccSectionOptions => string.IsNullOrWhiteSpace(dccSectionOptions.AppId))) - throw new ArgumentException("sections with an empty AppId are not allowed", nameof(dccOptions)); + dccOptions.ExpandSections.ForEach(section => + { + MasaArgumentException.ThrowIfNullOrWhiteSpace(section.AppId); + }); if (dccOptions.ExpandSections.DistinctBy(dccSectionOptions => dccSectionOptions.AppId).Count() != dccOptions.ExpandSections.Count) throw new ArgumentException("AppId cannot be repeated", nameof(dccOptions)); diff --git a/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/MasaDbContext.cs b/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/MasaDbContext.cs index 863702333..7b90a73c3 100644 --- a/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/MasaDbContext.cs +++ b/src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/MasaDbContext.cs @@ -136,14 +136,14 @@ public sealed override int SaveChanges(bool acceptAllChangesOnSuccess) protected virtual void OnBeforeSaveChanges() { - UpdateRowVesion(ChangeTracker); + UpdateRowVersion(ChangeTracker); OnBeforeSaveChangesByFilters(); DomainEventEnqueueAsync(ChangeTracker).ConfigureAwait(false).GetAwaiter().GetResult(); } protected virtual async Task OnBeforeSaveChangesAsync() { - UpdateRowVesion(ChangeTracker); + UpdateRowVersion(ChangeTracker); OnBeforeSaveChangesByFilters(); await DomainEventEnqueueAsync(ChangeTracker); } @@ -184,7 +184,7 @@ protected virtual async Task DomainEventEnqueueAsync(ChangeTracker changeTracker await DomainEventBus.Enqueue(domainEvent); } - protected virtual void UpdateRowVesion(ChangeTracker changeTracker) + protected virtual void UpdateRowVersion(ChangeTracker changeTracker) { if (ConcurrencyStampProvider == null) return; diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs index 18c650cd3..4851be2d3 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs +++ b/src/Contrib/Dispatcher/IntegrationEvents/Masa.Contrib.Dispatcher.IntegrationEvents/Options/DispatcherOptions.cs @@ -190,8 +190,7 @@ public int DeleteBatchCount public DispatcherOptions(IServiceCollection services, Assembly[] assemblies) : this(services) { - if (assemblies == null || assemblies.Length == 0) - throw new ArgumentException(nameof(assemblies)); + MasaArgumentException.ThrowIfNullOrEmptyCollection(assemblies); Assemblies = assemblies; AllEventTypes = assemblies diff --git a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Options/DispatcherOptions.cs b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Options/DispatcherOptions.cs index d0067205a..a1eed5285 100644 --- a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Options/DispatcherOptions.cs +++ b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events/Options/DispatcherOptions.cs @@ -21,8 +21,7 @@ private bool IsSupportUnitOfWork(Type eventType) public DispatcherOptions(IServiceCollection services, Assembly[] assemblies) : this(services) { - if (assemblies == null || assemblies.Length == 0) - throw new ArgumentException(nameof(assemblies)); + MasaArgumentException.ThrowIfNullOrEmptyCollection(assemblies); Assemblies = assemblies; AllEventTypes = assemblies diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj new file mode 100644 index 000000000..8d856d70d --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + Masa.Contrib.Exceptions.Zh_CN + enable + enable + + + + + Always + + + + + + + + diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Resources/i18n/framework/zh-CN.json b/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Resources/i18n/framework/zh-CN.json new file mode 100644 index 000000000..52e227eda --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Resources/i18n/framework/zh-CN.json @@ -0,0 +1,15 @@ +{ + "MFARG0001": "参数错误. (Parameter '{0}')", + "MFARG0002": "值不能为null. (Parameter '{0}')", + "MFARG0003": "值不能为null和Empty. (Parameter '{0}')", + "MFARG0004": "值不能为null和WhiteSpace. (Parameter '{0}')", + "MFARG0005": "值必须介于{1}-{2} . (Parameter '{0}')", + "MFARG0006": "值必须大于{1}. (Parameter '{0}')", + "MFARG0007": "值必须大于或等于{1}. (Parameter '{0}')", + "MFARG0008": "值必须小于{1}. (Parameter '{0}')", + "MFARG0009": "值必须小于或等于{1}. (Parameter '{0}')", + "MFARG0010": "值不能包含{1}. (Parameter '{0}')", + "MFARG0011": "值不能包含{1}或{2}. (Parameter '{0}')", + "MFARG0012": "值不能为null或空集合. (Parameter '{0}')", + "MFSer0001": "内部服务出错" +} \ No newline at end of file diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index 5ed330801..f1ebdda68 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -8,44 +8,7 @@ namespace Microsoft.AspNetCore.Builder; public static class ApplicationBuilderExtensions { /// - /// Use localizable - /// - /// - /// - /// - [Obsolete("UseMasaExceptionHandler is recommended to use instead.")] - public static IApplicationBuilder UseMasaExceptionHandling( - this IApplicationBuilder app, - Action? exceptionHandlingOptions = null) - { - return app.UseMasaExceptionHandling(_ => - { - }, exceptionHandlingOptions); - } - - /// - /// Use localizable - /// - /// - /// - /// - /// - [Obsolete("UseMasaExceptionHandler is recommended to use instead.")] - public static IApplicationBuilder UseMasaExceptionHandling( - this IApplicationBuilder app, - Action action, - Action? exceptionHandlingOptions) - { - var option = new MasaExceptionHandlingOptions(); - exceptionHandlingOptions?.Invoke(option); - - app.UseMiddleware(Options.Create(option)); - app.UseRequestLocalization(action); - return app; - } - - /// - /// Use localizable + /// Use localizable /// /// /// @@ -60,7 +23,7 @@ public static IApplicationBuilder UseMasaExceptionHandler( } /// - /// Use localizable + /// Use localizable /// /// /// diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs index 61b734129..83d0f780c 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs @@ -20,7 +20,7 @@ public static IMvcBuilder AddMasaExceptionHandler(this IMvcBuilder builder, Acti builder.Services.Configure(options => { - options.Filters.Add(); + options.Filters.Add(); }); builder.Services.Configure(action); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index b2d0ea189..568e23f43 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -3,9 +3,6 @@ // ReSharper disable once CheckNamespace -using System.Net; -using Microsoft.Extensions.Options; - namespace Microsoft.AspNetCore.Builder; public class ExceptionHandlerMiddleware @@ -27,7 +24,10 @@ public ExceptionHandlerMiddleware( _logger = logger; } - public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceProvider) + public async Task InvokeAsync(HttpContext httpContext, + IServiceProvider serviceProvider, + I18N? frameworkI18N = null, + II18N? i18N = null) { try { @@ -58,19 +58,19 @@ await httpContext.Response.WriteTextAsync( return; } - _logger?.WriteLog(masaExceptionContext.Exception, - masaExceptionContext.Exception is UserFriendlyException ? LogLevel.Information : LogLevel.Error, - _logRelationOptions); + _logger?.WriteLog(masaExceptionContext.Exception, _logRelationOptions); + + var httpStatusCode = masaExceptionContext.Exception.GetHttpStatusCode(); - if (masaExceptionContext.Exception is UserFriendlyException) + if (masaExceptionContext.Exception is MasaException masaException) { - await httpContext.Response.WriteTextAsync((int)MasaHttpStatusCode.UserFriendlyException, - masaExceptionContext.Exception.Message); + await httpContext.Response.WriteTextAsync(httpStatusCode, masaException.GetMessage(frameworkI18N, i18N)); } - else if (masaExceptionContext.Exception is MasaException || _options.CatchAllException) + else if (_options.CatchAllException) { - var message = Constant.DEFAULT_EXCEPTION_MESSAGE; - await httpContext.Response.WriteTextAsync((int)HttpStatusCode.InternalServerError, message); + string message = frameworkI18N == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : + frameworkI18N[ErrorCode.INTERNAL_SERVER_ERROR]; + await httpContext.Response.WriteTextAsync(httpStatusCode, message); } else { diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlingMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlingMiddleware.cs deleted file mode 100644 index 3a7770d3a..000000000 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlingMiddleware.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Microsoft.AspNetCore.Builder; - -public class ExceptionHandlingMiddleware -{ - private readonly RequestDelegate _next; - private readonly ILogger? _logger; - private readonly MasaExceptionHandlingOptions _options; - - public ExceptionHandlingMiddleware( - RequestDelegate next, - ILogger? logger, - IOptions options) - { - _next = next; - _logger = logger; - _options = options.Value; - } - - public async Task InvokeAsync(HttpContext httpContext) - { - try - { - await _next(httpContext); - } - catch (Exception exception) - { - if (_options.CustomExceptionHandler is not null) - { - var handlerResult = _options.CustomExceptionHandler.Invoke(exception); - - if (handlerResult.ExceptionHandled) return; - - if (handlerResult.OverrideException is not null) exception = handlerResult.OverrideException; - } - if (exception is UserFriendlyException) - { - var message = exception.Message; - _logger?.LogError(exception, message); - await httpContext.Response.WriteTextAsync((int)MasaHttpStatusCode.UserFriendlyException, message); - } - else if (exception is MasaException || _options.CatchAllException) - { - var message = Constant.DEFAULT_EXCEPTION_MESSAGE; - _logger?.LogError(exception, message); - await httpContext.Response.WriteTextAsync((int)HttpStatusCode.InternalServerError, message); - } - else - { - throw; - } - } - } -} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/GlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs similarity index 55% rename from src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/GlobalExceptionFilter.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs index 4a7424f70..8c9761798 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/GlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs @@ -3,30 +3,34 @@ // ReSharper disable once CheckNamespace -using Microsoft.Extensions.Options; - namespace Microsoft.AspNetCore.Mvc.Filters; /// /// Mvc pipeline exception filter to catch global exception /// -public class MvcGlobalExcetionFilter : IExceptionFilter +public class MvcGlobalExceptionFilter : IExceptionFilter { private readonly IServiceProvider _serviceProvider; private readonly IMasaExceptionHandler? _masaExceptionHandler; private readonly MasaExceptionHandlerOptions _options; private readonly MasaExceptionLogRelationOptions _logRelationOptions; - private readonly ILogger? _logger; + private readonly ILogger? _logger; + private readonly I18N? _frameworkI18N; + private readonly II18N? _i18N; - public MvcGlobalExcetionFilter(IServiceProvider serviceProvider, + public MvcGlobalExceptionFilter(IServiceProvider serviceProvider, IOptions options, IOptions logRelationOptions, - ILogger? logger = null) + I18N? frameworkI18N = null, + II18N? i18N = null, + ILogger? logger = null) { _serviceProvider = serviceProvider; _options = options.Value; - _masaExceptionHandler = ExceptionHandlerExtensions.GetMasaExceptionHandler(serviceProvider, _options.MasaExceptionHandlerType); + _masaExceptionHandler = serviceProvider.GetMasaExceptionHandler(_options.MasaExceptionHandlerType); _logRelationOptions = logRelationOptions.Value; + _frameworkI18N = frameworkI18N; + _i18N = i18N; _logger = logger; } @@ -49,26 +53,33 @@ public void OnException(ExceptionContext context) { context.ExceptionHandled = true; context.Result = new DefaultExceptionResult( - masaExceptionContext.Message, + masaExceptionContext.Message!, masaExceptionContext.StatusCode, masaExceptionContext.ContentType); return; } - _logger?.WriteLog(masaExceptionContext.Exception, - masaExceptionContext.Exception is UserFriendlyException ? LogLevel.Information : LogLevel.Error, - _logRelationOptions); + _logger?.WriteLog(masaExceptionContext.Exception, _logRelationOptions); + + var httpStatusCode = masaExceptionContext.Exception.GetHttpStatusCode(); - if (masaExceptionContext.Exception is UserFriendlyException userFriendlyException) + if (masaExceptionContext.Exception is MasaException masaException) { context.ExceptionHandled = true; - context.Result = new UserFriendlyExceptionResult(userFriendlyException.Message); + context.Result = new DefaultExceptionResult(masaException.GetMessage(_frameworkI18N, _i18N), + httpStatusCode, + masaExceptionContext.ContentType); return; } - if (masaExceptionContext.Exception is MasaException || _options.CatchAllException) + if (_options.CatchAllException) { context.ExceptionHandled = true; - context.Result = new InternalServerErrorObjectResult(Constant.DEFAULT_EXCEPTION_MESSAGE); + + string message = _frameworkI18N == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : + _frameworkI18N[ErrorCode.INTERNAL_SERVER_ERROR]; + context.Result = new DefaultExceptionResult(message, + httpStatusCode, + masaExceptionContext.ContentType); return; } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs index bfce3e65e..46318c457 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs @@ -7,5 +7,5 @@ internal static class Constant { public const string DEFAULT_HTTP_CONTENT_TYPE = "text/plain; charset=utf-8"; - public const string DEFAULT_EXCEPTION_MESSAGE = "An error occur in masa framework."; + // public const string DEFAULT_EXCEPTION_MESSAGE = "An error occur in masa framework."; } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs index 4ead86360..cc2fe0c3d 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs @@ -1,20 +1,53 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -// ReSharper disable once CheckNamespace - -namespace System; +namespace Masa.Contrib.Exceptions.Internal; internal static class ExceptionExtensions { - public static void WriteLog( - this ILogger logger, - Exception exception, - LogLevel defaultLogLevel, - MasaExceptionLogRelationOptions logRelationOptions, - string? message = null) + public static int GetHttpStatusCode(this Exception exception) + { + if (exception is UserFriendlyException) + return (int)MasaHttpStatusCode.UserFriendlyException; + + return (int)HttpStatusCode.InternalServerError; + } + + public static string GetMessage(this MasaException masaException, II18N? frameworkI18N, II18N? i18N) { - var logLevel = logRelationOptions.GetLogLevel(exception, defaultLogLevel); - logger.Log(logLevel, exception, message ?? exception.Message); + if (!string.IsNullOrWhiteSpace(masaException.ErrorCode)) + { + if (!masaException.ErrorCode.StartsWith(ErrorCode.FRAMEWORK_PREFIX, StringComparison.OrdinalIgnoreCase)) + { + if (i18N != null) + return i18N[masaException.ErrorCode, masaException.Parameters]; + + if (masaException.ErrorMessage != null) + return string.Format(masaException.ErrorMessage, masaException.Parameters); + + return masaException.Message; + } + if (masaException is MasaArgumentException masaArgumentException) + { + if (frameworkI18N != null) + return frameworkI18N[masaException.ErrorCode, new List() + { + masaArgumentException.ParamName!, + masaArgumentException.Parameters + }]; + if (masaArgumentException.ErrorMessage != null) + return string.Format(masaArgumentException.ErrorMessage, masaException.Parameters); + + return masaArgumentException.Message; + } + if (frameworkI18N != null) + return frameworkI18N[masaException.ErrorCode, masaException.Parameters]; + + if (masaException.ErrorMessage != null) + return string.Format(masaException.ErrorMessage, masaException.Parameters); + + return masaException.Message; + } + return masaException.Message; } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs new file mode 100644 index 000000000..7ba077a39 --- /dev/null +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs @@ -0,0 +1,30 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +internal static class LoggerExtensions +{ + public static void WriteLog( + this ILogger logger, + Exception exception, + MasaExceptionLogRelationOptions logRelationOptions, + string? message = null) + { + LogLevel defaultLogLevel = LogLevel.Error; + if (exception is MasaException masaException) + { + if (masaException.LogLevel != null) + { + logger.Log(masaException.LogLevel!.Value, exception, message); + return; + } + if(masaException is UserFriendlyException) + defaultLogLevel = LogLevel.Information; + } + var logLevel = logRelationOptions.GetLogLevel(exception, defaultLogLevel); + logger.Log(logLevel, exception, message); + } +} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ServiceProviderExtensions.cs similarity index 96% rename from src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs rename to src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ServiceProviderExtensions.cs index 668dd3f13..280c0694d 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionHandlerExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ServiceProviderExtensions.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Exceptions.Internal; -internal static class ExceptionHandlerExtensions +internal static class ServiceProviderExtensions { public static IMasaExceptionHandler? GetMasaExceptionHandler(this IServiceProvider serviceProvider, Type? masaExceptionHandlerType) { diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj index 281f369a9..6f15bd598 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs index 330c88bb1..2ca2563c4 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs @@ -13,8 +13,8 @@ public class MasaExceptionHandlerOptions internal Type? MasaExceptionHandlerType { get; private set; } - public void UseExceptionHanlder() where TExceptionHanlder : IMasaExceptionHandler + public void UseExceptionHandler() where TExceptionHandler : IMasaExceptionHandler { - MasaExceptionHandlerType = typeof(TExceptionHanlder); + MasaExceptionHandlerType = typeof(TExceptionHandler); } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs deleted file mode 100644 index f923670f3..000000000 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlingOptions.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace System; - -public class MasaExceptionHandlingOptions -{ - public bool CatchAllException { get; set; } = true; - - public Func? CustomExceptionHandler { get; set; } -} diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs index 90b3a2465..afec35e17 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs @@ -7,13 +7,13 @@ namespace Microsoft.AspNetCore.Mvc; public class DefaultExceptionResult : IActionResult { - public string? Message { get; set; } + public string Message { get; set; } public int StatusCode { get; set; } public string ContentType { get; set; } - public DefaultExceptionResult(string? message, int statusCode, string contentType) + public DefaultExceptionResult(string message, int statusCode, string contentType) { Message = message; StatusCode = statusCode; @@ -22,6 +22,6 @@ public DefaultExceptionResult(string? message, int statusCode, string contentTyp public async Task ExecuteResultAsync(ActionContext context) { - await context.HttpContext.Response.WriteTextAsync(StatusCode, Message ?? Constant.DEFAULT_EXCEPTION_MESSAGE, ContentType); + await context.HttpContext.Response.WriteTextAsync(StatusCode, Message, ContentType); } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs index 36d5bc563..58410c25d 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs @@ -11,3 +11,5 @@ global using Microsoft.Extensions.Options; global using Microsoft.AspNetCore.Mvc; global using Microsoft.AspNetCore.Mvc.Filters; +global using Masa.BuildingBlocks.Data.Constants; +global using Masa.BuildingBlocks.Globalization.I18N; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index cf8386b35..4ee7c032f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -3,6 +3,8 @@ // ReSharper disable once CheckNamespace +using Masa.Contrib.Globalization.I18N.Internal; + namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions @@ -83,7 +85,13 @@ private static IServiceCollection AddI18NCore( services.AddOptions(); services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); services.TryAddSingleton(); - + services.Configure(options => + { + options.Resources + .Add() + .AddJson(Constant.DEFAULT_RESOURCE_PATH); + }); + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs index 445b1ba9e..515b11a46 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs @@ -8,4 +8,6 @@ internal static class Constant internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; internal const string DEFAULT_RESOURCE_PATH = "Resources/i18n"; + + internal const string DEFAULT_FRAMEWORK_RESOURCE_PATH = "Resources/i18n/framework"; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs index a77fb43da..de55b8ff8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18N.Internal; -public static class JsonConfigurationUtils +internal static class JsonConfigurationUtils { internal static void AddJson(string languageDirectory, string supportCultureName, diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/DefaultStorageClient.cs b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/DefaultStorageClient.cs index 00dc3b101..a73d37eb5 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/DefaultStorageClient.cs +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/DefaultStorageClient.cs @@ -20,7 +20,7 @@ public TemporaryCredentialsResponse GetSecurityToken() { if (OptionProvider.IncompleteStsOptions) throw new ArgumentException( - $"Sts options is imcomplete, {nameof(AliyunStsOptions.RegionId)} or {nameof(Options.RoleArn)} or {nameof(Options.RoleSessionName)} cannot be empty or null"); + $"Sts options is incomplete, {nameof(AliyunStsOptions.RegionId)} or {nameof(Options.RoleArn)} or {nameof(Options.RoleSessionName)} cannot be empty or null"); return CredentialProvider.GetSecurityToken(); } diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/ObjectStorageExtensions.cs b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/ObjectStorageExtensions.cs index 8b4ca44fc..a773f2ebd 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/ObjectStorageExtensions.cs +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/Internal/ObjectStorageExtensions.cs @@ -7,9 +7,8 @@ internal static class ObjectStorageExtensions { internal static string CheckNullOrEmptyAndReturnValue(string? parameter, string parameterName) { - if (string.IsNullOrEmpty(parameter)) - throw new ArgumentException($"{parameterName} cannot be null and empty string"); + MasaArgumentException.ThrowIfNullOrWhiteSpace(parameter, parameterName); - return parameter; + return parameter!; } } diff --git a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs index 698bbc50f..45f3c345c 100644 --- a/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs +++ b/src/Contrib/Storage/ObjectStorage/Masa.Contrib.Storage.ObjectStorage.Aliyun/ServiceCollectionExtensions.cs @@ -107,11 +107,7 @@ private static IOptionsMonitor GetAliyunStorageCo private static void CheckAliYunStorageOptions(AliyunStorageOptions options) { - ArgumentNullException.ThrowIfNull(options, nameof(options)); - - if (options.AccessKeyId == null && options.AccessKeySecret == null) - throw new ArgumentException( - $"{nameof(options.AccessKeyId)}, {nameof(options.AccessKeySecret)} are required and cannot be empty"); + MasaArgumentException.ThrowIfNull(options); ObjectStorageExtensions.CheckNullOrEmptyAndReturnValue(options.AccessKeyId, nameof(options.AccessKeyId)); ObjectStorageExtensions.CheckNullOrEmptyAndReturnValue(options.AccessKeySecret, nameof(options.AccessKeySecret)); diff --git a/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/Utils/AttributeUtils.cs b/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/Utils/AttributeUtils.cs new file mode 100644 index 000000000..fb603a7ec --- /dev/null +++ b/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/Utils/AttributeUtils.cs @@ -0,0 +1,32 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public static class AttributeUtils +{ + public static string? GetDescriptionByConst(string fieldName, BindingFlags? bindingFlags = null) + => GetDescriptionByConst(typeof(TClass), fieldName, bindingFlags); + + public static string? GetDescriptionByConst(Type type, string fieldName, BindingFlags? bindingFlags = null) + { + var fieldInfo = type.GetField(fieldName, bindingFlags ?? BindingFlags.Public | BindingFlags.Static); + if (fieldInfo == null) + return null; + + return GetDescriptionByField(fieldInfo); + } + + public static string? GetDescriptionByField(FieldInfo fieldInfo) + => GetFieldAttributeValue(fieldInfo, attribute => attribute.Description); + + public static TOpt? GetFieldAttributeValue( + FieldInfo fieldInfo, + Func valueSelector) + where TAttribute : Attribute + { + return fieldInfo.GetCustomAttributes(typeof(TAttribute), true).FirstOrDefault() is TAttribute att ? valueSelector(att) : default; + } +} diff --git a/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/AttributeTest.cs b/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/AttributeTest.cs new file mode 100644 index 000000000..14f2b141a --- /dev/null +++ b/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/AttributeTest.cs @@ -0,0 +1,21 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Utils.Extensions.DotNet.Tests; + +[TestClass] +public class AttributeTest +{ + [TestMethod] + public void TestGetDescriptionByConst() + { + var value = AttributeUtils.GetDescriptionByConst(typeof(ErrorCode), nameof(ErrorCode.FRAMEWORK_PREFIX)); + Assert.AreEqual("Framework Prefix", value); + } +} + +public static class ErrorCode +{ + [System.ComponentModel.Description("Framework Prefix")] + public const string FRAMEWORK_PREFIX = "MF"; +} From b949a6df21b71a0addbd7ea7db8d99b1fc425369 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 3 Nov 2022 19:03:23 +0800 Subject: [PATCH 18/38] feat(Exception): Modify Exception --- .../Handlers/ExceptionHandlerMiddleware.cs | 7 +++-- .../Extensions/ServiceCollectionExtensions.cs | 16 +++++------- .../Internal/JsonConfigurationUtils.cs | 26 ++++++++++++------- .../Json/JsonConfigurationProvider.cs | 4 +++ .../_Imports.cs | 1 + 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index 568e23f43..d2df15c21 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -24,11 +24,10 @@ public ExceptionHandlerMiddleware( _logger = logger; } - public async Task InvokeAsync(HttpContext httpContext, - IServiceProvider serviceProvider, - I18N? frameworkI18N = null, - II18N? i18N = null) + public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceProvider) { + var frameworkI18N = serviceProvider.GetService>(); + var i18N = serviceProvider.GetService>(); try { await _next(httpContext); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index 4ee7c032f..d22a5cc5d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -3,8 +3,6 @@ // ReSharper disable once CheckNamespace -using Masa.Contrib.Globalization.I18N.Internal; - namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions @@ -14,8 +12,8 @@ public static IServiceCollection AddI18N( Action? action = null, params LanguageInfo[] languages) => services.AddI18N( - Masa.Contrib.Globalization.I18N.Internal.Constant.DEFAULT_RESOURCE_PATH, - Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, + Constant.DEFAULT_RESOURCE_PATH, + Constant.SUPPORTED_CULTURES_NAME, action, languages); @@ -26,7 +24,7 @@ public static IServiceCollection AddI18N( params LanguageInfo[] languages) => services.AddI18N( languageDirectory, - Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, + Constant.SUPPORTED_CULTURES_NAME, action, languages); @@ -46,8 +44,8 @@ public static IServiceCollection TestAddI18N( Action? action = null, params LanguageInfo[] languages) => services.TestAddI18N( - Masa.Contrib.Globalization.I18N.Internal.Constant.DEFAULT_RESOURCE_PATH, - Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, + Constant.DEFAULT_RESOURCE_PATH, + Constant.SUPPORTED_CULTURES_NAME, action, languages); @@ -58,7 +56,7 @@ public static IServiceCollection TestAddI18N( params LanguageInfo[] languages) => services.TestAddI18N( languageDirectory, - Masa.Contrib.Globalization.I18N.Internal.Constant.SUPPORTED_CULTURES_NAME, + Constant.SUPPORTED_CULTURES_NAME, action, languages); @@ -91,7 +89,7 @@ private static IServiceCollection AddI18NCore( .Add() .AddJson(Constant.DEFAULT_RESOURCE_PATH); }); - + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs index de55b8ff8..92d88859e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs @@ -15,14 +15,14 @@ internal static void AddJson(string languageDirectory, if (languages.Length == 0) { languages = GetLanguageInfos(languageDirectory, supportCultureName).ToArray(); - MonitorChange(languageDirectory, supportCultureName, () => - { - I18NResourceResourceConfiguration.Languages = GetLanguageInfos(languageDirectory, supportCultureName).ToList(); - I18NResourceResourceConfiguration - .Resources - .Add() - .AddJson(languageDirectory, I18NResourceResourceConfiguration.Languages.ToArray()); - }); + // MonitorChange(languageDirectory, supportCultureName, () => + // { + // I18NResourceResourceConfiguration.Languages = GetLanguageInfos(languageDirectory, supportCultureName).ToList(); + // I18NResourceResourceConfiguration + // .Resources + // .Add() + // .AddJson(languageDirectory, I18NResourceResourceConfiguration.Languages.ToArray()); + // }); } I18NResourceResourceConfiguration.Languages = languages.ToList(); @@ -46,7 +46,15 @@ private static List GetLanguageInfos( goto start; } } - catch (IOException) + catch (FileNotFoundException ex) + { + //todo: Write a log, prompting to use English by default + return new List() + { + new("en-us", "English") + }; + } + catch (IOException ex) { Task.Delay(300); goto start; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs index 8dee9e6bc..b93501aaa 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs @@ -13,6 +13,10 @@ public JsonConfigurationProvider(JsonConfigurationSource configurationSource) protected override IConfigurationBuilder AddFile(IConfigurationBuilder configurationBuilder, string basePath, string cultureName) { + var filePath = Path.Combine(basePath, cultureName + ".json"); + if (!File.Exists(filePath)) + return configurationBuilder; + return configurationBuilder .SetBasePath(basePath) .AddJsonFile(cultureName + ".json", false, true); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index 1498f8f2d..bb24730e9 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -5,6 +5,7 @@ global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Globalization.I18N; global using Masa.Contrib.Globalization.I18N; +global using Masa.Contrib.Globalization.I18N.Internal; global using Masa.Contrib.Globalization.I18N.Json; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; From c88a0bf8aa1bea5e60b0863f4c1c7df6036c5f33 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Fri, 4 Nov 2022 20:09:55 +0800 Subject: [PATCH 19/38] feat(Globalization): Add I18N --- Masa.Framework.sln | 36 +++-- .../Extensions/ConfigurationExtensions.cs | 4 +- .../Masa.BuildingBlocks.Exceptions.csproj | 1 + .../MasaArgumentException.cs | 10 ++ .../MasaException.cs | 80 ++++++++++ .../_Imports.cs | 4 +- .../{Const.cs => Constant.cs} | 2 +- .../CultureModel.cs | 20 +++ .../CultureSettings.cs | 23 +++ .../DefaultLanguageProvider.cs | 29 +++- .../I18NOfT.cs | 59 +++++-- .../I18NResource.cs | 7 +- .../I18NResourceDictionary.cs | 23 ++- .../I18NResourceResourceConfiguration.cs | 2 - .../II18N.cs | 2 + .../LanguageInfo.cs | 15 +- .../Options/MasaI18NOptions.cs | 1 + .../{ => Resources}/DefaultResource.cs | 2 + .../MasaExceptionResource.cs} | 4 +- .../Resources/MasaFrameworkResource.cs | 14 ++ .../Resources/MasaLanguageResource.cs | 11 ++ .../_Imports.cs | 1 + .../ApplicationBuilderExtensions.cs | 18 --- .../Handlers/ExceptionHandlerMiddleware.cs | 5 +- .../Handlers/MvcGlobalExceptionFilter.cs | 9 +- .../Internal/ExceptionExtensions.cs | 38 ----- .../MasaExceptionContext.cs | 2 + .../Masa.Contrib.Exceptions/_Imports.cs | 18 +-- .../ApplicationBuilderExtensions.cs | 27 ++++ ...ntrib.Globalization.I18N.AspNetCore.csproj | 17 ++ .../_Imports.cs | 7 + .../I18NOfT.cs | 2 +- .../ServiceCollectionExtensions.cs | 27 +--- .../_Imports.cs | 2 - .../Extensions/I18NOptionsExtensions.cs | 36 +---- .../Extensions/I18NResourceExtensions.cs | 5 +- .../Extensions/I18NResourceExtensions.cs | 39 +++-- .../Extensions/ServiceCollectionExtensions.cs | 151 +++++++++++------- .../FileConfigurationProvider.cs | 11 +- .../Internal/Constant.cs | 4 + .../Internal/CultureUtils.cs | 52 ++++++ .../Internal/JsonConfigurationUtils.cs | 75 --------- .../Internal/PathHelper.cs | 15 -- .../Internal/PathUtils.cs | 16 ++ .../LocalI18NResourceContributor.cs | 10 +- .../Masa.Contrib.Globalization.I18N.csproj | 8 + .../Options/I18NOptions.cs | 5 +- .../Masa.Contrib.Globalization.I18N/README.md | 2 - .../README.zh-CN.md | 2 - .../i18n/framework/exceptions/en-US.json | 15 ++ .../i18n/framework/languages/en-US.json | 4 + .../_Imports.cs | 2 +- ...a.Contrib.Globalization.I18N.zh-CN.csproj} | 6 +- .../i18n/framework/exceptions}/zh-CN.json | 0 .../i18n/framework/languages/zh-CN.json | 4 + .../_Imports.cs | 1 - .../I18NTest.cs | 3 +- .../_Imports.cs | 1 - 58 files changed, 627 insertions(+), 362 deletions(-) rename src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/{Const.cs => Constant.cs} (89%) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs rename src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/{ => Resources}/DefaultResource.cs (84%) rename src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/{MasaDefaultResource.cs => Resources/MasaExceptionResource.cs} (77%) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/exceptions/en-US.json create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/languages/en-US.json rename src/Contrib/{Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj => Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj} (59%) rename src/Contrib/{Exception/Masa.Contrib.Exceptions.Zh-CN/Resources/i18n/framework => Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/exceptions}/zh-CN.json (100%) create mode 100644 src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/languages/zh-CN.json diff --git a/Masa.Framework.sln b/Masa.Framework.sln index c238b0d49..7dd65078d 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -626,10 +626,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Excepti EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Exceptions", "src\Contrib\Exception\Masa.Contrib.Exceptions\Masa.Contrib.Exceptions.csproj", "{C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Exceptions.Zh-CN", "src\Contrib\Exception\Masa.Contrib.Exceptions.Zh-CN\Masa.Contrib.Exceptions.Zh-CN.csproj", "{AC032E31-83E5-4A50-A4A6-F18E67BA9475}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Exceptions.Tests", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions.Tests\Masa.BuildingBlocks.Exceptions.Tests.csproj", "{921DCAAC-3146-4EDB-891C-D76089E4A451}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.AspNetCore\Masa.Contrib.Globalization.I18N.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resources", "Resources", "{95A0DD72-2C64-4C00-A201-94CD7E5BB3F4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.zh-CN", "src\Contrib\Globalization\Resources\Masa.Contrib.Globalization.I18N.zh-CN\Masa.Contrib.Globalization.I18N.zh-CN.csproj", "{EACF8A3A-13A9-4BAF-81B6-0C651993FC17}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2206,14 +2210,6 @@ Global {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|Any CPU.Build.0 = Release|Any CPU {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|x64.ActiveCfg = Release|Any CPU {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}.Release|x64.Build.0 = Release|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|x64.ActiveCfg = Debug|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Debug|x64.Build.0 = Debug|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|Any CPU.Build.0 = Release|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|x64.ActiveCfg = Release|Any CPU - {AC032E31-83E5-4A50-A4A6-F18E67BA9475}.Release|x64.Build.0 = Release|Any CPU {921DCAAC-3146-4EDB-891C-D76089E4A451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {921DCAAC-3146-4EDB-891C-D76089E4A451}.Debug|Any CPU.Build.0 = Debug|Any CPU {921DCAAC-3146-4EDB-891C-D76089E4A451}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2222,6 +2218,22 @@ Global {921DCAAC-3146-4EDB-891C-D76089E4A451}.Release|Any CPU.Build.0 = Release|Any CPU {921DCAAC-3146-4EDB-891C-D76089E4A451}.Release|x64.ActiveCfg = Release|Any CPU {921DCAAC-3146-4EDB-891C-D76089E4A451}.Release|x64.Build.0 = Release|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Debug|x64.ActiveCfg = Debug|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Debug|x64.Build.0 = Debug|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Release|Any CPU.Build.0 = Release|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Release|x64.ActiveCfg = Release|Any CPU + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Release|x64.Build.0 = Release|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|x64.ActiveCfg = Debug|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|x64.Build.0 = Debug|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|Any CPU.Build.0 = Release|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|x64.ActiveCfg = Release|Any CPU + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2529,8 +2541,10 @@ Global {F17FFB29-A622-4430-B2EA-E9FF20E68122} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} {145400E0-7AC3-4D7B-88D1-F17847E4FA6D} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48} = {F17FFB29-A622-4430-B2EA-E9FF20E68122} - {AC032E31-83E5-4A50-A4A6-F18E67BA9475} = {F17FFB29-A622-4430-B2EA-E9FF20E68122} {921DCAAC-3146-4EDB-891C-D76089E4A451} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} + {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {95A0DD72-2C64-4C00-A201-94CD7E5BB3F4} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {EACF8A3A-13A9-4BAF-81B6-0C651993FC17} = {95A0DD72-2C64-4C00-A201-94CD7E5BB3F4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs b/src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs index a2f8e8f4b..49e8f9c03 100644 --- a/src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs +++ b/src/BuildingBlocks/Configuration/Masa.BuildingBlocks.Configuration/Extensions/ConfigurationExtensions.cs @@ -1,13 +1,15 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Microsoft.Extensions.DependencyInjection; public static class ConfigurationExtensions { public static Dictionary ConvertToDictionary(this IConfiguration configuration) { - var data = new Dictionary(); + var data = new Dictionary(StringComparer.OrdinalIgnoreCase); GetData(configuration, configuration.GetChildren(), ref data); return data; } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj index 78fb7d643..853ac2f07 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -9,6 +9,7 @@ + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs index 646a0e94a..e7fe8da0b 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -171,4 +171,14 @@ public static void ThrowIf(bool condition, string? paramName, string errorCode, [DoesNotReturn] private static void Throw(string? paramName, string errorCode, string? errorMessage, params object[] parameters) => throw new MasaArgumentException(paramName, errorCode, errorMessage, parameters); + + protected override object[] GetParameters() + { + var parameters = new List() + { + ParamName! + }; + parameters.AddRange(Parameters); + return parameters.ToArray(); + } } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index 402654afa..db8ce73bf 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -19,6 +19,57 @@ public class MasaException : Exception public object[] Parameters { get; private set; } + private bool _initialize; + + private II18N? _i18N; + + internal II18N? I18N + { + get + { + TryInitialize(); + return _i18N; + } + } + + private II18N? _frameworkI18N; + + internal II18N? FrameworkI18N + { + get + { + TryInitialize(); + return _frameworkI18N; + } + } + + private bool _supportI18N; + + internal bool SupportI18N + { + get + { + TryInitialize(); + return _supportI18N; + } + } + + private void TryInitialize() + { + if (_initialize) + return; + + Initialize(); + } + + private void Initialize() + { + _frameworkI18N = MasaApp.GetService>(); + _i18N = MasaApp.GetService>(); + _supportI18N = _frameworkI18N != null; + _initialize = true; + } + public MasaException() { } @@ -50,4 +101,33 @@ public MasaException(SerializationInfo serializationInfo, StreamingContext conte : base(serializationInfo, context) { } + + public string GetLocalizationMessage() + { + if (string.IsNullOrWhiteSpace(ErrorCode)) + return Message; + + return GetLocalizationMessageExecuting(); + } + + protected virtual string GetLocalizationMessageExecuting() + { + if (!SupportI18N) + { + if (string.IsNullOrWhiteSpace(ErrorMessage)) + return Message; + + return string.Format(ErrorMessage, GetParameters()); + } + + if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) + { + //The current framework frame exception + return FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; + } + + return I18N!.T(ErrorCode, false, GetParameters()) ?? Message; + } + + protected virtual object[] GetParameters() => Parameters; } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs index 108ae447d..b8c377e57 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs @@ -1,7 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Globalization.I18N; global using Microsoft.Extensions.Logging; global using System.Diagnostics.CodeAnalysis; -global using System.Runtime.Serialization; global using System.Runtime.CompilerServices; +global using System.Runtime.Serialization; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Const.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs similarity index 89% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Const.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs index 03880d93e..4eb65631d 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Const.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs @@ -3,7 +3,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public static class Const +public static class Constant { public const string DEFAULT_LOCAL_SECTION = "I18N"; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs new file mode 100644 index 000000000..ec674d744 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +public class CultureModel +{ + public string Culture { get; set; } + + public string DisplayName { get; set; } + + public string Icon { get; set; } + + public CultureModel(string culture, string displayName, string? icon = null) + { + Culture = culture; + DisplayName = displayName; + Icon = icon ?? string.Empty; + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs new file mode 100644 index 000000000..6e4be2602 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs @@ -0,0 +1,23 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +public class CultureSettings +{ + public string DefaultCulture { get; set; } + + public string? ResourcesDirectory { get; set; } + + public string? SupportCultureName { get; set; } + + public List SupportedCultures { get; set; } = new(); + + public void AddCulture(string culture, string displayName, string? icon = null) + => AddCulture(new CultureModel(culture, displayName, icon)); + + public void AddCulture(CultureModel cultureModel) + { + SupportedCultures.Add(cultureModel); + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs index 311c856d9..45e9a574e 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs @@ -5,5 +5,32 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public class DefaultLanguageProvider : ILanguageProvider { - public IReadOnlyList GetLanguages() => I18NResourceResourceConfiguration.Languages.ToArray(); + private readonly II18N _i18N; + private readonly IOptions _options; + + public DefaultLanguageProvider(II18N i18N, IOptions options) + { + _i18N = i18N; + _options = options; + } + + public IReadOnlyList GetLanguages() + { + var list = new List(); + string cultureName = _i18N.GetCultureInfo().Name; + _options.Value.SupportedCultures.ForEach(culture => + { + string key = culture.Culture.Equals(cultureName, StringComparison.OrdinalIgnoreCase) ? + nameof(LanguageInfo.UIDisplayName) : + $"{culture.Culture}\\.{nameof(LanguageInfo.UIDisplayName)}"; + var uiDisplayName = _i18N.T(key); + var languageInfo = new LanguageInfo(culture.Culture, culture.DisplayName, culture.Icon) + { + UIDisplayName = uiDisplayName + }; + + list.Add(languageInfo); + }); + return list; + } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs index 51a8b74c0..a25e802b1 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs @@ -3,9 +3,10 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public class I18N : II18N +public class I18NOfT : II18N { private readonly I18NResource? _resource; + private readonly List _baseResources; public string this[string name] => T(name); @@ -15,9 +16,13 @@ public class I18N : II18N public string? this[string name, bool returnKey, params object[] arguments] => T(name, returnKey, arguments); - public I18N() + public I18NOfT() { _resource = I18NResourceResourceConfiguration.Resources.GetOrNull(); + + _baseResources = _resource?.BaseResourceTypes + .Select(resourceType => I18NResourceResourceConfiguration.Resources.GetOrNull(resourceType)) + .ToList() ?? new List(); } public virtual string T(string name) @@ -30,14 +35,42 @@ public virtual string T(string name) /// Return Key when key does not exist, default: true /// public virtual string? T(string name, bool returnKey) + => Core(name, returnKey, out _); + + /// + /// Gets the string resource with the given name. + /// + /// The name of the string resource. + /// Return Key when key does not exist, default: true + /// does it exist + /// + public string? Core(string name, bool returnKey, out bool isExist) { - var resourceContributor = _resource?.GetResourceContributor(GetCultureInfo()); - if (resourceContributor != null) + isExist = true; + var value = GetOrNull(name); + if (value == null) { - return resourceContributor.GetOrNull(name) ?? (returnKey ? name : null); + foreach (var resource in _baseResources) + { + value = GetOrNull(resource, name); + if (value != null) + return value; + } + isExist = false; + return returnKey ? name : null; } + return value; + } - return returnKey ? name : null; + public virtual string? GetOrNull(string name) => GetOrNull(_resource, name); + + public virtual string? GetOrNull(I18NResource? i18NResource, string name) + { + if (i18NResource == null) + return null; + + var resourceContributor = i18NResource.GetResourceContributor(GetCultureInfo()); + return resourceContributor?.GetOrNull(name); } public virtual string T(string name, params object[] arguments) @@ -47,11 +80,12 @@ public virtual string T(string name, params object[] arguments) { ArgumentNullException.ThrowIfNull(name); - var value = T(name, returnKey); - if (value != null) - return string.Format(GetCultureInfo(), value, arguments); + var value = Core(name, returnKey, out bool isExist); - return null; + if (isExist) + return string.Format(GetCultureInfo(), value!, arguments); + + return returnKey ? name : null; } public virtual CultureInfo GetCultureInfo() => CultureInfo.CurrentUICulture; @@ -59,8 +93,5 @@ public virtual string T(string name, params object[] arguments) public virtual void SetCulture(string cultureName, bool useUserOverride = true) => SetCulture(new CultureInfo(cultureName, useUserOverride)); - public virtual void SetCulture(CultureInfo culture) - { - CultureInfo.CurrentUICulture = culture; - } + public virtual void SetCulture(CultureInfo culture) => CultureInfo.CurrentUICulture = culture; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs index b96bce990..4cbc3275b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs @@ -9,13 +9,16 @@ public class I18NResource public Type ResourceType { get; } - public I18NResource(Type resourceType) + public Type[] BaseResourceTypes { get; } + + public I18NResource(Type resourceType, Type[] baseResourceTypes) { _dictionary = new(StringComparer.OrdinalIgnoreCase); ResourceType = resourceType; + BaseResourceTypes = baseResourceTypes; } - public void AddContributor(string cultureName,II18NResourceContributor localizationResourceContributor) + public void AddContributor(string cultureName, II18NResourceContributor localizationResourceContributor) { if (_dictionary.ContainsKey(cultureName)) throw new ArgumentException($"The {cultureName} already exists with {ResourceType.FullName}"); diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs index 39cdfb1a4..0aa785efc 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs @@ -6,14 +6,29 @@ namespace Masa.BuildingBlocks.Globalization.I18N; [Serializable] public class I18NResourceDictionary : Dictionary { - public I18NResource Add() + public I18NResource Add(params Type[] baseResourceTypes) { - return Add(typeof(TResource)); + return Add(typeof(TResource), baseResourceTypes); } - public I18NResource Add(Type resourceType) + public I18NResource Add(Type resourceType, params Type[] baseResourceTypes) { - return this[resourceType] = new I18NResource(resourceType); + return this[resourceType] = new I18NResource(resourceType, baseResourceTypes); + } + + public bool TryAdd(Action action, params Type[] baseResourceTypes) + { + return TryAdd(typeof(TResource), action, baseResourceTypes); + } + + public bool TryAdd(Type resourceType, Action action, params Type[] baseResourceTypes) + { + if (this.ContainsKey(resourceType)) + return false; + + var i18NResource = Add(resourceType, baseResourceTypes); + action.Invoke(i18NResource); + return true; } public I18NResource? GetOrNull(Type resourceType) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs index c8b8d3b89..acead8b1b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs @@ -8,6 +8,4 @@ public static class I18NResourceResourceConfiguration public static readonly string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; public static I18NResourceDictionary Resources { get; set; } = new(); - - public static IEnumerable Languages { get; set; } = new List(); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs index a643f1bae..f2b7a0370 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs @@ -60,6 +60,8 @@ public interface II18N /// The values to format the string with. string? T(string name, bool returnKey, params object[] arguments); + CultureInfo GetCultureInfo(); + /// /// Set the CultureName for the current request /// diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs index 75763f9e7..77a9a5a14 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs @@ -5,17 +5,22 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public class LanguageInfo { - public bool DefaultCulture { get; set; } = false; - public string Culture { get; set; } - public string Display { get; set; } + public string DisplayName { get; set; } public string Icon { get; set; } - public LanguageInfo(string culture, string? display = null) + // ReSharper disable once InconsistentNaming + /// + /// Content displayed for the current language + /// + public string? UIDisplayName { get; set; } + + public LanguageInfo(string culture, string displayName, string? icon = null) { Culture = culture; - Display = display ?? culture; + DisplayName = displayName; + Icon = icon ?? string.Empty; } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs index e91af76c1..627fba350 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + namespace Masa.BuildingBlocks.Globalization.I18N; public class MasaI18NOptions diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs similarity index 84% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs index 06523b878..b43ff527e 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Masa.BuildingBlocks.Globalization.I18N; public class DefaultResource diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/MasaDefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaExceptionResource.cs similarity index 77% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/MasaDefaultResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaExceptionResource.cs index 2ba555410..1acf9f0e2 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/MasaDefaultResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaExceptionResource.cs @@ -1,12 +1,14 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// ReSharper disable once CheckNamespace + namespace Masa.BuildingBlocks.Globalization.I18N; /// /// Framework Multilingual Resources /// -public class MasaDefaultResource +public class MasaExceptionResource { } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs new file mode 100644 index 000000000..fcce4cabd --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs @@ -0,0 +1,14 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.BuildingBlocks.Globalization.I18N; + +/// +/// Framework Multilingual Resources +/// +public class MasaFrameworkResource +{ + +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs new file mode 100644 index 000000000..67006b40b --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.BuildingBlocks.Globalization.I18N; + +public class MasaLanguageResource +{ + +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index 38d9e107b..b51383891 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -1,4 +1,5 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Microsoft.Extensions.Options; global using System.Globalization; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index f1ebdda68..7493634b7 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -16,29 +16,11 @@ public static class ApplicationBuilderExtensions public static IApplicationBuilder UseMasaExceptionHandler( this IApplicationBuilder app, Action? exceptionHandlingOptions = null) - { - return app.UseMasaExceptionHandler(_ => - { - }, exceptionHandlingOptions); - } - - /// - /// Use localizable - /// - /// - /// - /// - /// - public static IApplicationBuilder UseMasaExceptionHandler( - this IApplicationBuilder app, - Action action, - Action? exceptionHandlingOptions) { var option = new MasaExceptionHandlerOptions(); exceptionHandlingOptions?.Invoke(option); app.UseMiddleware(Options.Create(option)); - app.UseRequestLocalization(action); return app; } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index d2df15c21..2effeeb4f 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -26,8 +26,7 @@ public ExceptionHandlerMiddleware( public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceProvider) { - var frameworkI18N = serviceProvider.GetService>(); - var i18N = serviceProvider.GetService>(); + var frameworkI18N = serviceProvider.GetService>(); try { await _next(httpContext); @@ -63,7 +62,7 @@ await httpContext.Response.WriteTextAsync( if (masaExceptionContext.Exception is MasaException masaException) { - await httpContext.Response.WriteTextAsync(httpStatusCode, masaException.GetMessage(frameworkI18N, i18N)); + await httpContext.Response.WriteTextAsync(httpStatusCode, masaException.GetLocalizationMessage()); } else if (_options.CatchAllException) { diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs index 8c9761798..7b511509a 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs @@ -14,15 +14,13 @@ public class MvcGlobalExceptionFilter : IExceptionFilter private readonly IMasaExceptionHandler? _masaExceptionHandler; private readonly MasaExceptionHandlerOptions _options; private readonly MasaExceptionLogRelationOptions _logRelationOptions; + private readonly I18NOfT? _frameworkI18N; private readonly ILogger? _logger; - private readonly I18N? _frameworkI18N; - private readonly II18N? _i18N; public MvcGlobalExceptionFilter(IServiceProvider serviceProvider, IOptions options, IOptions logRelationOptions, - I18N? frameworkI18N = null, - II18N? i18N = null, + I18NOfT? frameworkI18N = null, ILogger? logger = null) { _serviceProvider = serviceProvider; @@ -30,7 +28,6 @@ public MvcGlobalExceptionFilter(IServiceProvider serviceProvider, _masaExceptionHandler = serviceProvider.GetMasaExceptionHandler(_options.MasaExceptionHandlerType); _logRelationOptions = logRelationOptions.Value; _frameworkI18N = frameworkI18N; - _i18N = i18N; _logger = logger; } @@ -66,7 +63,7 @@ public void OnException(ExceptionContext context) if (masaExceptionContext.Exception is MasaException masaException) { context.ExceptionHandled = true; - context.Result = new DefaultExceptionResult(masaException.GetMessage(_frameworkI18N, _i18N), + context.Result = new DefaultExceptionResult(masaException.GetLocalizationMessage(), httpStatusCode, masaExceptionContext.ContentType); return; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs index cc2fe0c3d..2a3962787 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs @@ -12,42 +12,4 @@ public static int GetHttpStatusCode(this Exception exception) return (int)HttpStatusCode.InternalServerError; } - - public static string GetMessage(this MasaException masaException, II18N? frameworkI18N, II18N? i18N) - { - if (!string.IsNullOrWhiteSpace(masaException.ErrorCode)) - { - if (!masaException.ErrorCode.StartsWith(ErrorCode.FRAMEWORK_PREFIX, StringComparison.OrdinalIgnoreCase)) - { - if (i18N != null) - return i18N[masaException.ErrorCode, masaException.Parameters]; - - if (masaException.ErrorMessage != null) - return string.Format(masaException.ErrorMessage, masaException.Parameters); - - return masaException.Message; - } - if (masaException is MasaArgumentException masaArgumentException) - { - if (frameworkI18N != null) - return frameworkI18N[masaException.ErrorCode, new List() - { - masaArgumentException.ParamName!, - masaArgumentException.Parameters - }]; - if (masaArgumentException.ErrorMessage != null) - return string.Format(masaArgumentException.ErrorMessage, masaException.Parameters); - - return masaArgumentException.Message; - } - if (frameworkI18N != null) - return frameworkI18N[masaException.ErrorCode, masaException.Parameters]; - - if (masaException.ErrorMessage != null) - return string.Format(masaException.ErrorMessage, masaException.Parameters); - - return masaException.Message; - } - return masaException.Message; - } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs index cd4735f09..74429e364 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs @@ -3,6 +3,8 @@ // ReSharper disable once CheckNamespace +using Constant = Masa.Contrib.Exceptions.Internal.Constant; + namespace System; public class MasaExceptionContext diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs index 58410c25d..c48e9d349 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs @@ -1,15 +1,15 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Microsoft.AspNetCore.Http; -global using Microsoft.Extensions.Logging; -global using System.Text; -global using System.Reflection; -global using Microsoft.Extensions.DependencyInjection; +global using Masa.BuildingBlocks.Data.Constants; +global using Masa.BuildingBlocks.Globalization.I18N; global using Masa.Contrib.Exceptions.Internal; -global using System.Net; -global using Microsoft.Extensions.Options; +global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc; global using Microsoft.AspNetCore.Mvc.Filters; -global using Masa.BuildingBlocks.Data.Constants; -global using Masa.BuildingBlocks.Globalization.I18N; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using Microsoft.Extensions.Options; +global using System.Net; +global using System.Reflection; +global using System.Text; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs new file mode 100644 index 000000000..ca49f5a94 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -0,0 +1,27 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.AspNetCore.Builder; + +public static class ApplicationBuilderExtensions +{ + public static IApplicationBuilder UseI18N(this IApplicationBuilder app) + { + var settings = app.ApplicationServices.GetRequiredService>().Value; + + var requestLocalization = new RequestLocalizationOptions(); + + var cultures = settings.SupportedCultures.Select(x => x.Culture).ToArray(); + requestLocalization + .AddSupportedCultures(cultures) + .AddSupportedUICultures(cultures); + if (!string.IsNullOrWhiteSpace(settings.DefaultCulture)) + requestLocalization.DefaultRequestCulture = new RequestCulture(settings.DefaultCulture); + + requestLocalization.ApplyCurrentCultureToResponseHeaders = true; + app.UseRequestLocalization(requestLocalization); + return app; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj new file mode 100644 index 000000000..3908ba537 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs new file mode 100644 index 000000000..8926abd03 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs @@ -0,0 +1,7 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Globalization.I18N; +global using Microsoft.AspNetCore.Localization; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Options; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs index e72f0e7f1..6d63a83b4 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs @@ -4,7 +4,7 @@ namespace Masa.Contrib.Globalization.I18N.Blazor; [ExcludeFromCodeCoverage] -public class I18N : Masa.BuildingBlocks.Globalization.I18N.I18N +public class I18N : I18NOfT { private const string CULTURE_COOKIE_KEY = "Masa_I18nConfig_Culture"; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs index d0f5eef2a..47e369a50 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs @@ -8,33 +8,10 @@ namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { public static IServiceCollection AddI18NForBlazor(this IServiceCollection services, - Action? action = null, - params LanguageInfo[] languages) + Action? action = null) { services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); - services.AddI18N(action, languages); - return services; - } - - public static IServiceCollection AddI18NForBlazor( - this IServiceCollection services, - string languageDirectory, - Action? action = null, - params LanguageInfo[] languages) - { - services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); - return services.AddI18N(languageDirectory, action, languages); - } - - public static IServiceCollection AddI18NForBlazor( - this IServiceCollection services, - string languageDirectory, - string supportCultureName, - Action? action = null, - params LanguageInfo[] languages) - { - services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); - services.AddI18N(languageDirectory, supportCultureName, action, languages); + services.AddI18N(action); return services; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs index a0cb24e93..8cd6c12b1 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs @@ -2,8 +2,6 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Globalization.I18N; -global using Masa.Contrib.Globalization.I18N; -global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.JSInterop; global using System.Diagnostics.CodeAnalysis; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index 8387adcf8..4f4f180cc 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -7,46 +7,22 @@ namespace Masa.Contrib.Globalization.I18N; public static class I18NOptionsExtensions { - public static void UseDcc( - this I18NOptions i18NOptions, - params LanguageInfo[] languages) - => i18NOptions.UseDcc(Dcc.Internal.Constant.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Constant.SUPPORTED_CULTURES_NAME, languages); + public static void UseDcc(this I18NOptions i18NOptions) + => i18NOptions.UseDcc(Dcc.Internal.Constant.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Constant.SUPPORTED_CULTURES_NAME); public static void UseDcc( this I18NOptions i18NOptions, - string configObject, - string supportCultureName, - params LanguageInfo[] languages) - => i18NOptions.UseDcc(DccConfig.AppId, configObject, supportCultureName, languages); + string configObject) + => i18NOptions.UseDcc(DccConfig.AppId, configObject); public static void UseDcc( this I18NOptions i18NOptions, string appId, - string configObject, - string supportCultureName, - params LanguageInfo[] languages) + string configObject) { - var services = MasaApp.GetServices(); - if (languages.Length == 0) - { - var serviceProvider = services.BuildServiceProvider(); - var configurationApiClient = serviceProvider.GetRequiredService(); - languages = configurationApiClient.GetAsync>( - $"{configObject}.{supportCultureName}", - newLanguages - => - { - I18NResourceResourceConfiguration.Languages = newLanguages; - I18NResourceResourceConfiguration - .Resources - .Add() - .UseDcc(appId, configObject, newLanguages.ToArray()); - }).ConfigureAwait(false).GetAwaiter().GetResult().ToArray(); - } - I18NResourceResourceConfiguration.Languages = languages.ToList(); I18NResourceResourceConfiguration .Resources .Add() - .UseDcc(appId, configObject, languages); + .UseDcc(appId, configObject, i18NOptions.SupportedCultures); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs index 2cc5c9444..73ba81c79 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs @@ -11,11 +11,12 @@ public static I18NResource UseDcc( this I18NResource localizationResource, string appId, string configObject, - params LanguageInfo[] languages) + List supportedCultures) { var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); var masaConfiguration = serviceProvider.GetRequiredService(); - var contributors = languages.Select(language => new DccI18NResourceContributor(appId, configObject, language.Culture, masaConfiguration)).ToList(); + var contributors = supportedCultures + .Select(supportedCulture => new DccI18NResourceContributor(appId, configObject, supportedCulture.Culture, masaConfiguration)).ToList(); foreach (var contributor in contributors) { localizationResource.AddContributor(contributor.CultureName, contributor); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index 2ac2a2055..e59b4cc27 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -11,28 +11,35 @@ public static class I18NResourceExtensions private static IMasaConfiguration? _masaConfiguration; - public static void AddJson( + public static I18NResource AddJson( this I18NResource resource, - string languageDirectory, - params LanguageInfo[] languages) + string resourcesDirectory, + params CultureModel[] supportedCultures) + => resource.AddJson(resourcesDirectory, supportedCultures.ToList()); + + public static I18NResource AddJson( + this I18NResource resource, + string resourcesDirectory, + IEnumerable supportedCultures) { - if (!PathHelper.ParseLanguageDirectory(ref languageDirectory)) - return; + if (!PathUtils.ParseResourcesDirectory(ref resourcesDirectory)) + return resource; var resourceContributors = GetResourceContributors( resource, - languageDirectory, - languages); + resourcesDirectory, + supportedCultures); foreach (var resourceContributor in resourceContributors) { resource.AddContributor(resourceContributor.CultureName, resourceContributor); } + return resource; } private static List GetResourceContributors( I18NResource resource, - string languageDirectory, - IEnumerable languages) + string resourcesDirectory, + IEnumerable supportedCultures) { _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); _masaConfiguration ??= @@ -42,17 +49,17 @@ private static List GetResourceContributors( var useMasaConfiguration = _masaConfiguration != null; var configuration = AddJsonConfigurationSource( services, - languageDirectory, - languages, + resourcesDirectory, + supportedCultures, resource.ResourceType, _configuration, useMasaConfiguration); _configuration = configuration; - return languages.Select(languageInfo => (II18NResourceContributor)new LocalI18NResourceContributor + return supportedCultures.Select(supportedCulture => (II18NResourceContributor)new LocalI18NResourceContributor ( resource.ResourceType, - languageInfo.Culture, + supportedCulture.Culture, useMasaConfiguration ? _configuration.GetSection(SectionTypes.Local.ToString()) : _configuration! ) ) @@ -61,8 +68,8 @@ private static List GetResourceContributors( private static IConfiguration AddJsonConfigurationSource( IServiceCollection services, - string languageDirectory, - IEnumerable languages, + string resourcesDirectory, + IEnumerable supportedCultures, Type resourceType, IConfiguration? configuration, bool useMasaConfiguration) @@ -83,7 +90,7 @@ private static IConfiguration AddJsonConfigurationSource( } var configurationBuilder = new ConfigurationBuilder(); var jsonLocalizationConfigurationSource = - new JsonConfigurationSource(resourceType, languageDirectory, languages.Select(l => l.Culture), + new JsonConfigurationSource(resourceType, resourcesDirectory, supportedCultures.Select(c => c.Culture), useMasaConfiguration); configurationBuilder.Add(jsonLocalizationConfigurationSource); var localizationConfiguration = configurationBuilder.Build(); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index d22a5cc5d..f1c518adc 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -7,97 +7,130 @@ namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { - public static IServiceCollection AddI18N( - this IServiceCollection services, - Action? action = null, - params LanguageInfo[] languages) - => services.AddI18N( - Constant.DEFAULT_RESOURCE_PATH, - Constant.SUPPORTED_CULTURES_NAME, - action, - languages); - public static IServiceCollection AddI18N( this IServiceCollection services, string languageDirectory, - Action? action = null, - params LanguageInfo[] languages) - => services.AddI18N( - languageDirectory, - Constant.SUPPORTED_CULTURES_NAME, - action, - languages); + string? supportCultureName = null, + Action? action = null) + { + MasaArgumentException.ThrowIfNullOrWhiteSpace(languageDirectory); + return services.AddI18N(settings => + { + settings.ResourcesDirectory = languageDirectory; + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? Constant.SUPPORTED_CULTURES_NAME : supportCultureName; + settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); + + if (string.IsNullOrEmpty(settings.DefaultCulture)) + settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; + }, action); + } public static IServiceCollection AddI18N( this IServiceCollection services, - string languageDirectory, - string supportCultureName, - Action? action = null, - params LanguageInfo[] languages) + Action? settingsAction = null, + Action? action = null) { MasaApp.TrySetServiceCollection(services); - return services.AddI18NCore(languageDirectory, supportCultureName, languages); + return services.AddI18NCore(settingsAction, action); } - public static IServiceCollection TestAddI18N( - this IServiceCollection services, - Action? action = null, - params LanguageInfo[] languages) - => services.TestAddI18N( - Constant.DEFAULT_RESOURCE_PATH, - Constant.SUPPORTED_CULTURES_NAME, - action, - languages); - public static IServiceCollection TestAddI18N( this IServiceCollection services, string languageDirectory, - Action? action = null, - params LanguageInfo[] languages) - => services.TestAddI18N( - languageDirectory, - Constant.SUPPORTED_CULTURES_NAME, - action, - languages); + string? supportCultureName = null, + Action? action = null) + { + MasaArgumentException.ThrowIfNullOrWhiteSpace(languageDirectory); + return services.TestAddI18N(settings => + { + settings.ResourcesDirectory = languageDirectory; + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? Constant.SUPPORTED_CULTURES_NAME : supportCultureName; + settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); + + if (string.IsNullOrEmpty(settings.DefaultCulture)) + settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; + }, action); + } public static IServiceCollection TestAddI18N( this IServiceCollection services, - string languageDirectory, - string supportCultureName, - Action? action = null, - params LanguageInfo[] languages) + Action? settingsAction = null, + Action? action = null) { MasaApp.SetServiceCollection(services); - services.AddI18NCore(languageDirectory, supportCultureName, languages); - I18NOptions i18NOptions = new I18NOptions(services); - action?.Invoke(i18NOptions); - return services; + return services.AddI18NCore(settingsAction, action); } private static IServiceCollection AddI18NCore( this IServiceCollection services, - string languageDirectory, - string supportCultureName, - params LanguageInfo[] languages) + Action? settingsAction, + Action? action = null) { services.AddOptions(); - services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); - services.TryAddSingleton(); + services.TryAddTransient(typeof(II18N<>), typeof(I18NOfT<>)); + if (settingsAction != null) + { + services.Configure(settingsAction); + } + else + { + services.Configure(settings => + { + if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) + settings.ResourcesDirectory = Constant.DEFAULT_RESOURCE_PATH; + + if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) + settings.SupportCultureName = Constant.SUPPORTED_CULTURES_NAME; + + if (!settings.SupportedCultures.Any()) + settings.SupportedCultures = + CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName); + + if (string.IsNullOrEmpty(settings.DefaultCulture)) + settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; + }); + } + + CultureSettings? languageSettings = null; services.Configure(options => { - options.Resources - .Add() - .AddJson(Constant.DEFAULT_RESOURCE_PATH); + var localLanguageSettings = languageSettings; + if (localLanguageSettings == null) + { + var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); + localLanguageSettings = serviceProvider.GetService>()!.Value; + } + + //todo: wait for auto-detection + options.Resources.TryAdd(resource + => resource.AddJson(Constant.DEFAULT_FRAMEWORK_RESOURCE_PATH, localLanguageSettings.SupportedCultures), + typeof(MasaExceptionResource)); + + options.Resources.TryAdd(resource + => resource.AddJson(Constant.DEFAULT_FRAMEWORK_EXCEPTION_RESOURCE_PATH, localLanguageSettings.SupportedCultures)); + + options.Resources.TryAdd(resource + => resource.AddJson(Constant.DEFAULT_FRAMEWORK_LANGUAGE_RESOURCE_PATH, localLanguageSettings.SupportedCultures)); + + options.Resources.TryAdd(resource + => resource.AddJson(localLanguageSettings.ResourcesDirectory ?? Constant.DEFAULT_RESOURCE_PATH, + localLanguageSettings.SupportedCultures)); }); + services.TryAddSingleton(); + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); - var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); - foreach (var resource in i18NOptions.Value.Resources) + var serviceProvider = services.BuildServiceProvider(); + if (action != null) { - I18NResourceResourceConfiguration.Resources[resource.Key] = resource.Value; + languageSettings = serviceProvider.GetRequiredService>().Value; + action.Invoke(new I18NOptions(services, languageSettings.SupportedCultures)); } - JsonConfigurationUtils.AddJson(languageDirectory, supportCultureName, languages); + + var i18NOptions = serviceProvider.GetRequiredService>(); + foreach (var resource in i18NOptions.Value.Resources) + I18NResourceResourceConfiguration.Resources[resource.Key] = resource.Value; return services; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs index 03695bf0e..f28ed4750 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs @@ -17,7 +17,7 @@ protected FileConfigurationProvider(JsonConfigurationSource configurationSource) _languageDirectory = configurationSource.LanguageDirectory; _cultureNames = configurationSource.CultureNames; _useMasaConfiguration = configurationSource.UseMasaConfiguration; - _dictionary = new(); + _dictionary = new(StringComparer.OrdinalIgnoreCase); } public override void Load() @@ -33,17 +33,18 @@ public override void Load() private string FormatKey(string cultureName) { + string localSection = BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION; var list = _useMasaConfiguration ? - new List() + new List { SectionTypes.Local.ToString(), - Const.DEFAULT_LOCAL_SECTION, + localSection, _resourceType, cultureName } : - new List() + new List { - Const.DEFAULT_LOCAL_SECTION, + localSection, _resourceType, cultureName }; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs index 515b11a46..fdefb68dc 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs @@ -10,4 +10,8 @@ internal static class Constant internal const string DEFAULT_RESOURCE_PATH = "Resources/i18n"; internal const string DEFAULT_FRAMEWORK_RESOURCE_PATH = "Resources/i18n/framework"; + + internal const string DEFAULT_FRAMEWORK_EXCEPTION_RESOURCE_PATH = "Resources/i18n/framework/exceptions"; + + internal const string DEFAULT_FRAMEWORK_LANGUAGE_RESOURCE_PATH = "Resources/i18n/framework/languages"; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs new file mode 100644 index 000000000..0265004f8 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs @@ -0,0 +1,52 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Internal; + +internal static class CultureUtils +{ + public static List GetSupportedCultures( + string languageDirectory, + string supportCultureName) + { + int retry = 0; + start: + try + { + var fileName = Path.Combine(languageDirectory, supportCultureName); + using var fileStream = new FileStream(fileName, FileMode.Open); + if (!fileStream.CanRead) + { + retry++; + if (retry <= 10) + { + Task.Delay(300); + goto start; + } + throw new FileLoadException("Failed to get supported languages", fileName); + } + } + catch (FileNotFoundException ex) + { + // //todo: Write a log, prompting to use English by default + return new List() + { + new("en-us", "English") + }; + } + catch (IOException ex) + { + retry++; + if (retry <= 10) + { + Task.Delay(300); + goto start; + } + throw; + } + + var supportCultureFilePath = Path.Combine(languageDirectory, supportCultureName); + var content = File.ReadAllText(supportCultureFilePath); + return System.Text.Json.JsonSerializer.Deserialize>(content)!; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs deleted file mode 100644 index 92d88859e..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/JsonConfigurationUtils.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N.Internal; - -internal static class JsonConfigurationUtils -{ - internal static void AddJson(string languageDirectory, - string supportCultureName, - params LanguageInfo[] languages) - { - if (!PathHelper.ParseLanguageDirectory(ref languageDirectory)) - return; - - if (languages.Length == 0) - { - languages = GetLanguageInfos(languageDirectory, supportCultureName).ToArray(); - // MonitorChange(languageDirectory, supportCultureName, () => - // { - // I18NResourceResourceConfiguration.Languages = GetLanguageInfos(languageDirectory, supportCultureName).ToList(); - // I18NResourceResourceConfiguration - // .Resources - // .Add() - // .AddJson(languageDirectory, I18NResourceResourceConfiguration.Languages.ToArray()); - // }); - } - - I18NResourceResourceConfiguration.Languages = languages.ToList(); - I18NResourceResourceConfiguration - .Resources - .Add() - .AddJson(languageDirectory, languages); - } - - private static List GetLanguageInfos( - string languageDirectory, - string supportCultureName) - { - start: - try - { - using var fileStream = new FileStream(Path.Combine(languageDirectory, supportCultureName), FileMode.Open); - if (!fileStream.CanRead) - { - Task.Delay(300); - goto start; - } - } - catch (FileNotFoundException ex) - { - //todo: Write a log, prompting to use English by default - return new List() - { - new("en-us", "English") - }; - } - catch (IOException ex) - { - Task.Delay(300); - goto start; - } - var supportCultureFilePath = Path.Combine(languageDirectory, supportCultureName); - var content = File.ReadAllText(supportCultureFilePath); - return System.Text.Json.JsonSerializer.Deserialize>(content)!; - } - - private static void MonitorChange(string filePath, string supportCultureName, Action onChange) - { - var fileProvider = new PhysicalFileProvider(filePath); - ChangeToken.OnChange( - () => fileProvider.Watch(supportCultureName), - onChange - ); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs deleted file mode 100644 index d0f94b0b0..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathHelper.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18N; - -internal static class PathHelper -{ - internal static bool ParseLanguageDirectory(ref string languageDirectory) - { - languageDirectory.CheckIsNullOrWhiteSpace(); - languageDirectory = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, languageDirectory.TrimStart("/")); - return Directory.Exists(languageDirectory); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs new file mode 100644 index 000000000..a1f299af1 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs @@ -0,0 +1,16 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.Contrib.Globalization.I18N; + +internal static class PathUtils +{ + internal static bool ParseResourcesDirectory(ref string resourcesPath) + { + resourcesPath.CheckIsNullOrWhiteSpace(); + resourcesPath = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, resourcesPath.TrimStart("/")); + return Directory.Exists(resourcesPath); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs index 68a3fb788..b28521d3a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs @@ -7,6 +7,11 @@ namespace Microsoft.Extensions.Localization; public class LocalI18NResourceContributor : II18NResourceContributor { + /// + /// Random number for handling special keys. + /// + private static readonly string _randomNumber = Guid.NewGuid().ToString(); + private readonly IConfiguration _configuration; public Type ResourceType { get; } @@ -25,10 +30,11 @@ public LocalI18NResourceContributor( public string? GetOrNull(string name) { - var section = _configuration.GetSection(Const.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); + var section = _configuration.GetSection(Masa.BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); if (section != null && section.Exists()) { - return section.GetValue(name.Replace(".", ConfigurationPath.KeyDelimiter)); + string newName = name.Replace("\\.", _randomNumber).Replace(".", ConfigurationPath.KeyDelimiter).Replace(_randomNumber, "."); + return section.GetValue(newName); } return null; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index 77d18a4a3..b778d2e82 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -8,12 +8,20 @@ + + + + + + + Always + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs index 3f4f3f501..5a880b654 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs @@ -9,8 +9,11 @@ public class I18NOptions { public IServiceCollection Services { get; } - public I18NOptions(IServiceCollection services) + public List SupportedCultures { get; } + + public I18NOptions(IServiceCollection services, List supportedCultures) { Services = services; + SupportedCultures = supportedCultures; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md index a3c9e41d8..231d25e8a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md @@ -57,13 +57,11 @@ Install-Package Masa.Contrib.Globalization.I18N ``` supportedCultures.json [ { - "DefaultCulture": true, "Culture":"zh-CN", "Display":"Simplified Chinese", "Icon": "{Replace-Your-Icon}" }, { - "DefaultCulture": false, "Culture":"en-US", "Display":"English (United States)", "Icon": "{Replace-Your-Icon}" diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md index d7469112f..5c24484e8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md @@ -57,13 +57,11 @@ Install-Package Masa.Contrib.Globalization.I18N ``` supportedCultures.json [ { - "DefaultCulture": true, "Culture":"zh-CN", "Display":"中文简体", "Icon": "{Replace-Your-Icon}" }, { - "DefaultCulture": false, "Culture":"en-US", "Display":"English (United States)", "Icon": "{Replace-Your-Icon}" diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/exceptions/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/exceptions/en-US.json new file mode 100644 index 000000000..b99af84d6 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/exceptions/en-US.json @@ -0,0 +1,15 @@ +{ + "MFARG0001": "Value Error. (Parameter '{0}')", + "MFARG0002": "Value cannot be null. (Parameter '{0}')", + "MFARG0003": "Value cannot be null and empty. (Parameter '{0}')", + "MFARG0004": "Value cannot be null and WhiteSpace . (Parameter '{0}')", + "MFARG0005": "Value must be between {1}-{2} . (Parameter '{0}')", + "MFARG0006": "Value must be greater than {1} . (Parameter '{0}')", + "MFARG0007": "Value must be greater than or equal {1} . (Parameter '{0}')", + "MFARG0008": "Value must be less than {1} . (Parameter '{0}')", + "MFARG0009": "Value must be less than or equal {1} . (Parameter '{0}')", + "MFARG0010": "Value cannot contain {1}. (Parameter '{0}')", + "MFARG0011": "Value cannot contain {1} or {2}. (Parameter '{0}')", + "MFARG0012": "Value cannot be null or empty collection. (Parameter '{0}')", + "MFSer0001": "Internal service error" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/languages/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/languages/en-US.json new file mode 100644 index 000000000..225a21533 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/languages/en-US.json @@ -0,0 +1,4 @@ +{ + "UIDisplayName": "English (United States)", + "zh-CN.UIDisplayName": "Chinese (Simplified)" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index bb24730e9..5af5325d7 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -10,7 +10,7 @@ global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; -global using Microsoft.Extensions.FileProviders; global using Microsoft.Extensions.Localization; global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; +global using Constant = Masa.Contrib.Globalization.I18N.Internal.Constant; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj similarity index 59% rename from src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj rename to src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj index 8d856d70d..0e658f797 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Masa.Contrib.Exceptions.Zh-CN.csproj +++ b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj @@ -2,19 +2,19 @@ net6.0 - Masa.Contrib.Exceptions.Zh_CN + Masa.Contrib.Globalization.I18N.zh_CN enable enable - + Always - + diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Resources/i18n/framework/zh-CN.json b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/exceptions/zh-CN.json similarity index 100% rename from src/Contrib/Exception/Masa.Contrib.Exceptions.Zh-CN/Resources/i18n/framework/zh-CN.json rename to src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/exceptions/zh-CN.json diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/languages/zh-CN.json b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/languages/zh-CN.json new file mode 100644 index 000000000..3a7224488 --- /dev/null +++ b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/languages/zh-CN.json @@ -0,0 +1,4 @@ +{ + "UIDisplayName": "中文 (简体)", + "en-US.UIDisplayName": "英语 (美国)" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs index e44b9f6cd..f5c8cbc4c 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs @@ -1,4 +1,3 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. - diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs index 038c88694..4c50a26e9 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs @@ -11,7 +11,6 @@ public class I18NTest [TestInitialize] public void Initialize() { - I18NResourceResourceConfiguration.Languages = new List(); I18NResourceResourceConfiguration.Resources = new(); } @@ -35,7 +34,7 @@ public void TestLocalization(string cultureName, string expectedValue) } [DataTestMethod] - [DataRow("zh-CN", "吉姆")] + // [DataRow("zh-CN", "吉姆")] [DataRow("en-US", "Jim")] public void TestLocalization2(string cultureName, string expectedValue) { diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs index c4b2cf9bc..de244af28 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs @@ -5,4 +5,3 @@ global using Microsoft.AspNetCore.Builder; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.VisualStudio.TestTools.UnitTesting; -global using System.Globalization; From 6917d19e5ad4d58803e2abddf042e8a79d98879d Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 7 Nov 2022 13:58:05 +0800 Subject: [PATCH 20/38] feat(I18n): Support I18n --- .../Masa.BuildingBlocks.Exceptions.csproj | 4 +-- .../I18NOfT.cs | 13 ++++++-- .../II18N.cs | 27 ++++++++++++++-- .../ApplicationBuilderExtensions.cs | 7 +++- .../Extensions/MvcBuilderExtensions.cs | 2 -- .../Masa.Contrib.Exceptions.csproj | 1 + .../MasaExceptionContext.cs | 6 ++-- .../ApplicationBuilderExtensions.cs | 8 ++++- ...ntrib.Globalization.I18N.AspNetCore.csproj | 4 +-- .../Extensions/ServiceCollectionExtensions.cs | 32 ++++++++----------- .../Masa.Contrib.Globalization.I18N/README.md | 4 +-- .../README.zh-CN.md | 4 +-- .../Resources/i18n/supportedCultures.json | 4 +-- 13 files changed, 74 insertions(+), 42 deletions(-) diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj index 853ac2f07..af9c871f2 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -13,9 +13,7 @@ - - C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.8\Microsoft.Extensions.Logging.Abstractions.dll - + diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs index a25e802b1..673e55ac2 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs @@ -69,7 +69,7 @@ public virtual string T(string name) if (i18NResource == null) return null; - var resourceContributor = i18NResource.GetResourceContributor(GetCultureInfo()); + var resourceContributor = i18NResource.GetResourceContributor(GetUiCultureInfo()); return resourceContributor?.GetOrNull(name); } @@ -88,10 +88,17 @@ public virtual string T(string name, params object[] arguments) return returnKey ? name : null; } - public virtual CultureInfo GetCultureInfo() => CultureInfo.CurrentUICulture; + public virtual CultureInfo GetCultureInfo() => CultureInfo.CurrentCulture; public virtual void SetCulture(string cultureName, bool useUserOverride = true) => SetCulture(new CultureInfo(cultureName, useUserOverride)); - public virtual void SetCulture(CultureInfo culture) => CultureInfo.CurrentUICulture = culture; + public virtual void SetCulture(CultureInfo culture) => CultureInfo.CurrentCulture = culture; + + public virtual CultureInfo GetUiCultureInfo() => CultureInfo.CurrentUICulture; + + public virtual void SetUiCulture(string cultureName, bool useUserOverride = true) + => SetUiCulture(new CultureInfo(cultureName, useUserOverride)); + + public virtual void SetUiCulture(CultureInfo culture) => CultureInfo.CurrentUICulture = culture; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs index f2b7a0370..bef8c9a17 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs @@ -63,15 +63,38 @@ public interface II18N CultureInfo GetCultureInfo(); /// - /// Set the CultureName for the current request + /// Set the CultureName + /// Data used to define "regional options", standards, formats, etc /// /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). void SetCulture(string cultureName, bool useUserOverride = true); /// - /// Set the CultureName for the current request + /// Set the CultureName + /// Data used to define "regional options", standards, formats, etc /// /// void SetCulture(CultureInfo culture); + + /// + /// get interface language + /// + /// + CultureInfo GetUiCultureInfo(); + + /// + /// Set the CultureName for the current request + /// Used to set the interface language + /// + /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. + /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). + void SetUiCulture(string cultureName, bool useUserOverride = true); + + /// + /// Set the CultureName for the current request + /// Used to set the interface language + /// + /// + void SetUiCulture(CultureInfo culture); } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index 7493634b7..ccd73dec4 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -12,15 +12,20 @@ public static class ApplicationBuilderExtensions /// /// /// + /// Whether to enable i18n /// public static IApplicationBuilder UseMasaExceptionHandler( this IApplicationBuilder app, - Action? exceptionHandlingOptions = null) + Action? exceptionHandlingOptions = null, + bool useI18N = true) { var option = new MasaExceptionHandlerOptions(); exceptionHandlingOptions?.Invoke(option); + if (useI18N) app.UseI18N(); + app.UseMiddleware(Options.Create(option)); + return app; } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs index 83d0f780c..2f38a92ae 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs @@ -16,8 +16,6 @@ public static IMvcBuilder AddMasaExceptionHandler(this IMvcBuilder builder) public static IMvcBuilder AddMasaExceptionHandler(this IMvcBuilder builder, Action action) { - builder.Services.AddLocalization(); - builder.Services.Configure(options => { options.Filters.Add(); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj index 6f15bd598..0d5372eb1 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs index 74429e364..0af2275de 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs @@ -3,8 +3,6 @@ // ReSharper disable once CheckNamespace -using Constant = Masa.Contrib.Exceptions.Internal.Constant; - namespace System; public class MasaExceptionContext @@ -37,14 +35,14 @@ internal MasaExceptionContext(Exception exception, HttpContext httpContext, ISer HttpContext = httpContext; StatusCode = (int)MasaHttpStatusCode.UserFriendlyException; ExceptionHandled = false; - ContentType = Constant.DEFAULT_HTTP_CONTENT_TYPE; + ContentType = Masa.Contrib.Exceptions.Internal.Constant.DEFAULT_HTTP_CONTENT_TYPE; ServiceProvider = serviceProvider; } public void ToResult( string message, int statusCode = (int)MasaHttpStatusCode.UserFriendlyException, - string contentType = Constant.DEFAULT_HTTP_CONTENT_TYPE) + string contentType = Masa.Contrib.Exceptions.Internal.Constant.DEFAULT_HTTP_CONTENT_TYPE) { Message = message; StatusCode = statusCode; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index ca49f5a94..b72b7d722 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -7,8 +7,14 @@ namespace Microsoft.AspNetCore.Builder; public static class ApplicationBuilderExtensions { + private static bool _isInitialize = false; + public static IApplicationBuilder UseI18N(this IApplicationBuilder app) { + if (_isInitialize) + return app; + + _isInitialize = true; var settings = app.ApplicationServices.GetRequiredService>().Value; var requestLocalization = new RequestLocalizationOptions(); @@ -18,7 +24,7 @@ public static IApplicationBuilder UseI18N(this IApplicationBuilder app) .AddSupportedCultures(cultures) .AddSupportedUICultures(cultures); if (!string.IsNullOrWhiteSpace(settings.DefaultCulture)) - requestLocalization.DefaultRequestCulture = new RequestCulture(settings.DefaultCulture); + requestLocalization.SetDefaultCulture(settings.DefaultCulture); requestLocalization.ApplyCurrentCultureToResponseHeaders = true; app.UseRequestLocalization(requestLocalization); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj index 3908ba537..3da5d7f8d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj @@ -9,9 +9,9 @@ - + - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index f1c518adc..a4ab6c27d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -68,28 +68,23 @@ private static IServiceCollection AddI18NCore( { services.AddOptions(); services.TryAddTransient(typeof(II18N<>), typeof(I18NOfT<>)); - if (settingsAction != null) + services.Configure(settings => { - services.Configure(settingsAction); - } - else - { - services.Configure(settings => - { - if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) - settings.ResourcesDirectory = Constant.DEFAULT_RESOURCE_PATH; + settingsAction?.Invoke(settings); - if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) - settings.SupportCultureName = Constant.SUPPORTED_CULTURES_NAME; + if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) + settings.ResourcesDirectory = Constant.DEFAULT_RESOURCE_PATH; - if (!settings.SupportedCultures.Any()) - settings.SupportedCultures = - CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName); + if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) + settings.SupportCultureName = Constant.SUPPORTED_CULTURES_NAME; - if (string.IsNullOrEmpty(settings.DefaultCulture)) - settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; - }); - } + if (!settings.SupportedCultures.Any()) + settings.SupportedCultures = + CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName); + + if (string.IsNullOrEmpty(settings.DefaultCulture)) + settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; + }); CultureSettings? languageSettings = null; services.Configure(options => @@ -99,6 +94,7 @@ private static IServiceCollection AddI18NCore( { var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); localLanguageSettings = serviceProvider.GetService>()!.Value; + languageSettings ??= localLanguageSettings; } //todo: wait for auto-detection diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md index 231d25e8a..436e96557 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md @@ -58,12 +58,12 @@ Install-Package Masa.Contrib.Globalization.I18N [ { "Culture":"zh-CN", - "Display":"Simplified Chinese", + "DisplayName":"Simplified Chinese", "Icon": "{Replace-Your-Icon}" }, { "Culture":"en-US", - "Display":"English (United States)", + "DisplayName":"English (United States)", "Icon": "{Replace-Your-Icon}" } ] diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md index 5c24484e8..a4978b33d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md @@ -58,12 +58,12 @@ Install-Package Masa.Contrib.Globalization.I18N [ { "Culture":"zh-CN", - "Display":"中文简体", + "DisplayName":"中文简体", "Icon": "{Replace-Your-Icon}" }, { "Culture":"en-US", - "Display":"English (United States)", + "DisplayName":"English (United States)", "Icon": "{Replace-Your-Icon}" } ] diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json index c334e66de..f6e4fbb29 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json @@ -1,10 +1,10 @@ [ { "Culture": "zh-CN", - "Display": "中文简体" + "DisplayName": "中文简体" }, { "Culture": "en-US", - "Display": "English (United States)" + "DisplayName": "English (United States)" } ] \ No newline at end of file From 3df98728fca66cac971b112e76dcdc65ce294b58 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 7 Nov 2022 14:20:27 +0800 Subject: [PATCH 21/38] feat(I18N): Adjust I18n.Dcc --- .../Extensions/ApplicationBuilderExtensions.cs | 2 +- .../_Imports.cs | 1 - .../Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs | 2 +- .../Extensions/I18NOptionsExtensions.cs | 10 +++++----- .../Extensions/I18NResourceExtensions.cs | 4 ++-- .../Internal/Constant.cs | 4 +--- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index b72b7d722..162f294b8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -7,7 +7,7 @@ namespace Microsoft.AspNetCore.Builder; public static class ApplicationBuilderExtensions { - private static bool _isInitialize = false; + private static bool _isInitialize; public static IApplicationBuilder UseI18N(this IApplicationBuilder app) { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs index 8926abd03..d8cde5c86 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs @@ -2,6 +2,5 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Globalization.I18N; -global using Microsoft.AspNetCore.Localization; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Options; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs index 6d63a83b4..a3817530f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs @@ -25,7 +25,7 @@ public override CultureInfo GetCultureInfo() var cultureName = jsInProcess.Invoke("eval", $"{GET_COOKIE_JS}('{CULTURE_COOKIE_KEY}')"); return new CultureInfo(cultureName); } - return CultureInfo.CurrentUICulture; + return CultureInfo.CurrentCulture; } public override void SetCulture(CultureInfo culture) diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index 4f4f180cc..d6156d88e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -8,21 +8,21 @@ namespace Masa.Contrib.Globalization.I18N; public static class I18NOptionsExtensions { public static void UseDcc(this I18NOptions i18NOptions) - => i18NOptions.UseDcc(Dcc.Internal.Constant.DEFAULT_CONFIG_OBJECT_NAME, Dcc.Internal.Constant.SUPPORTED_CULTURES_NAME); + => i18NOptions.UseDcc(Dcc.Internal.Constant.CULTURES_NAME_PREFIX); public static void UseDcc( this I18NOptions i18NOptions, - string configObject) - => i18NOptions.UseDcc(DccConfig.AppId, configObject); + string configObjectPrefix) + => i18NOptions.UseDcc(DccConfig.AppId, configObjectPrefix); public static void UseDcc( this I18NOptions i18NOptions, string appId, - string configObject) + string configObjectPrefix) { I18NResourceResourceConfiguration .Resources .Add() - .UseDcc(appId, configObject, i18NOptions.SupportedCultures); + .UseDcc(appId, configObjectPrefix, i18NOptions.SupportedCultures); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs index 73ba81c79..d5d15b2a8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs @@ -10,13 +10,13 @@ public static class I18NResourceExtensions public static I18NResource UseDcc( this I18NResource localizationResource, string appId, - string configObject, + string configObjectPrefix, List supportedCultures) { var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); var masaConfiguration = serviceProvider.GetRequiredService(); var contributors = supportedCultures - .Select(supportedCulture => new DccI18NResourceContributor(appId, configObject, supportedCulture.Culture, masaConfiguration)).ToList(); + .Select(supportedCulture => new DccI18NResourceContributor(appId, configObjectPrefix, supportedCulture.Culture, masaConfiguration)).ToList(); foreach (var contributor in contributors) { localizationResource.AddContributor(contributor.CultureName, contributor); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs index 31fc2c314..15f510c3b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs @@ -5,7 +5,5 @@ namespace Masa.Contrib.Globalization.I18N.Dcc.Internal; internal static class Constant { - internal const string DEFAULT_CONFIG_OBJECT_NAME = "i18n"; - - internal const string SUPPORTED_CULTURES_NAME = "supportedCultures"; + internal const string CULTURES_NAME_PREFIX = "Culture"; } From 3b69b03771377c9ed5db2048303677e5e79b1883 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 7 Nov 2022 18:34:51 +0800 Subject: [PATCH 22/38] feat: Add I18N on Blazor Server --- .../I18NResource.cs | 4 +- .../I18NResourceDictionary.cs | 10 ++++- .../InheritResourceAttribute.cs | 15 +++++++ .../Resources/MasaFrameworkResource.cs | 1 + .../ApplicationBuilderExtensions.cs | 33 ++++++++++++++ .../I18NOfT.cs | 44 ++++++++++++------- ...a.Contrib.Globalization.I18N.Blazor.csproj | 1 + .../ServiceCollectionExtensions.cs | 13 ++++-- .../_Imports.cs | 4 ++ .../Extensions/ServiceCollectionExtensions.cs | 12 +++-- .../Internal/Constant.cs | 16 +++++-- .../Masa.Contrib.Globalization.I18N.csproj | 2 +- .../Framework/Exceptions}/en-US.json | 0 .../Framework/Languages}/en-US.json | 0 ...sa.Contrib.Globalization.I18N.zh-CN.csproj | 2 +- .../Framework/Exceptions}/zh-CN.json | 0 .../Framework/Languages}/zh-CN.json | 0 ...rib.Globalization.I18N.Blazor.Tests.csproj | 6 +-- .../I18NTest.cs | 2 +- ...sa.Contrib.Globalization.I18N.Tests.csproj | 18 ++++---- .../Resources/{i18n => I18n}/en-US.json | 0 .../{i18n => I18n}/supportedCultures.json | 0 .../Resources/{i18n => I18n}/zh-CN.json | 0 23 files changed, 134 insertions(+), 49 deletions(-) create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Extensions/ApplicationBuilderExtensions.cs rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{i18n/framework/exceptions => I18n/Framework/Exceptions}/en-US.json (100%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{i18n/framework/languages => I18n/Framework/Languages}/en-US.json (100%) rename src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/{i18n/framework/exceptions => I18n/Framework/Exceptions}/zh-CN.json (100%) rename src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/{i18n/framework/languages => I18n/Framework/Languages}/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{i18n => I18n}/en-US.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{i18n => I18n}/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{i18n => I18n}/zh-CN.json (100%) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs index 4cbc3275b..6b03c3b73 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs @@ -9,9 +9,9 @@ public class I18NResource public Type ResourceType { get; } - public Type[] BaseResourceTypes { get; } + public IEnumerable BaseResourceTypes { get; } - public I18NResource(Type resourceType, Type[] baseResourceTypes) + public I18NResource(Type resourceType, IEnumerable baseResourceTypes) { _dictionary = new(StringComparer.OrdinalIgnoreCase); ResourceType = resourceType; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs index 0aa785efc..edc3f497b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs @@ -13,7 +13,15 @@ public I18NResource Add(params Type[] baseResourceTypes) public I18NResource Add(Type resourceType, params Type[] baseResourceTypes) { - return this[resourceType] = new I18NResource(resourceType, baseResourceTypes); + List types = new List(baseResourceTypes); + + var customAttributes = resourceType.GetCustomAttributes(typeof(InheritResourceAttribute), true).FirstOrDefault(); + if (customAttributes is InheritResourceAttribute inheritResourceAttribute) + { + types.AddRange(inheritResourceAttribute.ResourceTypes); + } + + return this[resourceType] = new I18NResource(resourceType, types.Distinct()); } public bool TryAdd(Action action, params Type[] baseResourceTypes) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs new file mode 100644 index 000000000..ec7c987e9 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +[AttributeUsage(AttributeTargets.Class)] +public class InheritResourceAttribute : Attribute +{ + public Type[] ResourceTypes { get; } + + public InheritResourceAttribute(params Type[] resourceTypes) + { + ResourceTypes = resourceTypes; + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs index fcce4cabd..161873e71 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs @@ -8,6 +8,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; /// /// Framework Multilingual Resources /// +[InheritResource(typeof(MasaExceptionResource))] public class MasaFrameworkResource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Extensions/ApplicationBuilderExtensions.cs new file mode 100644 index 000000000..162f294b8 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Extensions/ApplicationBuilderExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.AspNetCore.Builder; + +public static class ApplicationBuilderExtensions +{ + private static bool _isInitialize; + + public static IApplicationBuilder UseI18N(this IApplicationBuilder app) + { + if (_isInitialize) + return app; + + _isInitialize = true; + var settings = app.ApplicationServices.GetRequiredService>().Value; + + var requestLocalization = new RequestLocalizationOptions(); + + var cultures = settings.SupportedCultures.Select(x => x.Culture).ToArray(); + requestLocalization + .AddSupportedCultures(cultures) + .AddSupportedUICultures(cultures); + if (!string.IsNullOrWhiteSpace(settings.DefaultCulture)) + requestLocalization.SetDefaultCulture(settings.DefaultCulture); + + requestLocalization.ApplyCurrentCultureToResponseHeaders = true; + app.UseRequestLocalization(requestLocalization); + return app; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs index a3817530f..e62889d1c 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs @@ -6,36 +6,46 @@ namespace Masa.Contrib.Globalization.I18N.Blazor; [ExcludeFromCodeCoverage] public class I18N : I18NOfT { - private const string CULTURE_COOKIE_KEY = "Masa_I18nConfig_Culture"; - - private const string GET_COOKIE_JS = - "(function(name){const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);const arr = document.cookie.match(reg);if (arr) {return unescape(arr[2]);}return null;})"; + private const string CULTURE_COOKIE_KEY = ".AspNetCore.Culture"; private const string SET_COOKIE_JS = "(function(name,value){ var Days = 30;var exp = new Date();exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);document.cookie = `${name}=${escape(value.toString())};path=/;expires=${exp.toUTCString()}`;})"; private readonly IJSRuntime _jsRuntime; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IOptions _options; - public I18N(IJSRuntime jsRuntime) => _jsRuntime = jsRuntime; - - public override CultureInfo GetCultureInfo() + public I18N(IJSRuntime jsRuntime, IHttpContextAccessor httpContextAccessor, IOptions options) { - if (_jsRuntime is IJSInProcessRuntime jsInProcess) - { - var cultureName = jsInProcess.Invoke("eval", $"{GET_COOKIE_JS}('{CULTURE_COOKIE_KEY}')"); - return new CultureInfo(cultureName); - } - return CultureInfo.CurrentCulture; + _jsRuntime = jsRuntime; + _httpContextAccessor = httpContextAccessor; + _options = options; } + public override CultureInfo GetCultureInfo() => GetSelectCulture().Culture; + + public override CultureInfo GetUiCultureInfo() => GetSelectCulture().UICulture; + public override void SetCulture(CultureInfo culture) + => SetCultureCore(culture, GetUiCultureInfo()); + + public override void SetUiCulture(CultureInfo culture) => SetCultureCore(GetCultureInfo(), culture); + + private RequestCulture GetSelectCulture() + { + var httpContext = _httpContextAccessor.HttpContext; + if (httpContext == null) return new RequestCulture(_options.Value.DefaultCulture); + + var requestCulture = httpContext.Features.Get(); + return requestCulture?.RequestCulture ?? new RequestCulture(_options.Value.DefaultCulture); + } + + private void SetCultureCore(CultureInfo culture, CultureInfo uiCulture) { try { - _jsRuntime.InvokeVoidAsync("eval", $"{SET_COOKIE_JS}('{CULTURE_COOKIE_KEY}','{culture.Name}')") - .ConfigureAwait(false) - .GetAwaiter() - .GetResult(); + var val = ($"c={culture.Name}|uic={uiCulture.Name}"); + _jsRuntime.InvokeVoidAsync("eval", $"{SET_COOKIE_JS}('{CULTURE_COOKIE_KEY}','{val}')"); } catch (Exception ex) { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj index 89999cfb6..38f145211 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs index 47e369a50..9b7ca29b0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs @@ -7,11 +7,18 @@ namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { - public static IServiceCollection AddI18NForBlazor(this IServiceCollection services, - Action? action = null) + public static IServiceCollection AddI18NForBlazor(this IServiceCollection services, Action? action = null) { + services.AddHttpContextAccessor(); services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); - services.AddI18N(action); + services.TryAddScoped(); + services.AddI18N(setting => + { + action?.Invoke(setting); + + if (setting.ResourcesDirectory.IsNullOrWhiteSpace()) + setting.ResourcesDirectory = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, "Resources", "I18n"); + }); return services; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs index 8cd6c12b1..11a677b53 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs @@ -2,7 +2,11 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Globalization.I18N; +global using Microsoft.AspNetCore.Http; +global using Microsoft.AspNetCore.Localization; +global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; +global using Microsoft.Extensions.Options; global using Microsoft.JSInterop; global using System.Diagnostics.CodeAnalysis; global using System.Globalization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index a4ab6c27d..caccbc0bb 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -73,7 +73,7 @@ private static IServiceCollection AddI18NCore( settingsAction?.Invoke(settings); if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) - settings.ResourcesDirectory = Constant.DEFAULT_RESOURCE_PATH; + settings.ResourcesDirectory = Constant.DefaultResourcePath; if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) settings.SupportCultureName = Constant.SUPPORTED_CULTURES_NAME; @@ -97,19 +97,17 @@ private static IServiceCollection AddI18NCore( languageSettings ??= localLanguageSettings; } - //todo: wait for auto-detection options.Resources.TryAdd(resource - => resource.AddJson(Constant.DEFAULT_FRAMEWORK_RESOURCE_PATH, localLanguageSettings.SupportedCultures), - typeof(MasaExceptionResource)); + => resource.AddJson(Constant.DefaultFrameworkResourcePath, localLanguageSettings.SupportedCultures)); options.Resources.TryAdd(resource - => resource.AddJson(Constant.DEFAULT_FRAMEWORK_EXCEPTION_RESOURCE_PATH, localLanguageSettings.SupportedCultures)); + => resource.AddJson(Constant.DefaultFrameworkExceptionResourcePath, localLanguageSettings.SupportedCultures)); options.Resources.TryAdd(resource - => resource.AddJson(Constant.DEFAULT_FRAMEWORK_LANGUAGE_RESOURCE_PATH, localLanguageSettings.SupportedCultures)); + => resource.AddJson(Constant.DefaultFrameworkLanguageResourcePath, localLanguageSettings.SupportedCultures)); options.Resources.TryAdd(resource - => resource.AddJson(localLanguageSettings.ResourcesDirectory ?? Constant.DEFAULT_RESOURCE_PATH, + => resource.AddJson(localLanguageSettings.ResourcesDirectory ?? Constant.DefaultResourcePath, localLanguageSettings.SupportedCultures)); }); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs index fdefb68dc..e4efdae3a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs @@ -7,11 +7,19 @@ internal static class Constant { internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; - internal const string DEFAULT_RESOURCE_PATH = "Resources/i18n"; + internal static readonly string DefaultResourcePath; - internal const string DEFAULT_FRAMEWORK_RESOURCE_PATH = "Resources/i18n/framework"; + internal static readonly string DefaultFrameworkResourcePath; - internal const string DEFAULT_FRAMEWORK_EXCEPTION_RESOURCE_PATH = "Resources/i18n/framework/exceptions"; + internal static readonly string DefaultFrameworkExceptionResourcePath; - internal const string DEFAULT_FRAMEWORK_LANGUAGE_RESOURCE_PATH = "Resources/i18n/framework/languages"; + internal static readonly string DefaultFrameworkLanguageResourcePath; + + static Constant() + { + DefaultResourcePath = Path.Combine("Resources", "I18n"); + DefaultFrameworkResourcePath = Path.Combine(DefaultResourcePath, "Framework"); + DefaultFrameworkExceptionResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Exceptions"); + DefaultFrameworkLanguageResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Languages"); + } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index b778d2e82..1c13d0a5a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -19,7 +19,7 @@ - + Always diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/exceptions/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/exceptions/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/languages/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/i18n/framework/languages/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj index 0e658f797..70399a08e 100644 --- a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj +++ b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj @@ -8,7 +8,7 @@ - + Always diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/exceptions/zh-CN.json b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Exceptions/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/exceptions/zh-CN.json rename to src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Exceptions/zh-CN.json diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/languages/zh-CN.json b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Languages/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/i18n/framework/languages/zh-CN.json rename to src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Languages/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj index 9cd2d4da1..6b6440e75 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj @@ -26,13 +26,13 @@ - + Always - + Always - + Always diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs index 4c50a26e9..8a05691e0 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs @@ -6,7 +6,7 @@ namespace Masa.Contrib.Globalization.I18N.Tests; [TestClass] public class I18NTest { - private const string DEFAULT_RESOURCE = "Resources/i18n"; + private const string DEFAULT_RESOURCE = "Resources/I18n"; [TestInitialize] public void Initialize() diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj index a4020544a..c221d710c 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -17,26 +17,26 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + - - + + - + Always - + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/i18n/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json From 282245f99cc829c66e3e5813bee504d2bbabe240 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Tue, 8 Nov 2022 19:34:07 +0800 Subject: [PATCH 23/38] feat(I18N): support WebAssembly --- BlazorApp2/wwwroot/appsettings.json | 10 ++ .../I18NResourceDictionary.cs | 17 ++- .../Options/I18NOptions.cs | 2 +- .../_Imports.cs | 2 + .../ApplicationBuilderExtensions.cs | 0 .../ServiceCollectionExtensions.cs | 6 +- .../I18NOfT.cs | 10 +- ...ib.Globalization.I18N.BlazorServer.csproj} | 0 .../_Imports.cs | 2 +- .../Extensions/I18NResourceExtensions.cs | 133 ++++++++++++++++++ .../Extensions/ServiceCollectionExtensions.cs | 79 +++++++++++ .../WebAssemblyHostBuilderExtensions.cs | 15 ++ .../I18NOfT.cs | 55 ++++++++ .../Internal/Constant.cs | 27 ++++ .../Internal/CultureUtils.cs | 38 +++++ .../Json/JsonConfigurationProvider.cs | 74 ++++++++++ .../Json/JsonConfigurationSource.cs | 29 ++++ .../LocalI18NResourceContributor.cs | 41 ++++++ ...lobalization.I18N.BlazorWebAssembly.csproj | 19 +++ .../_Imports.cs | 19 +++ .../Extensions/ServiceCollectionExtensions.cs | 6 +- .../Internal/CultureUtils.cs | 9 +- .../Masa.Contrib.Globalization.I18N.csproj | 11 +- ...sa.Contrib.Globalization.I18N.zh-CN.csproj | 26 ++-- ...rib.Globalization.I18N.Blazor.Tests.csproj | 8 +- .../ServicesCollectionsTest.cs | 6 +- 26 files changed, 601 insertions(+), 43 deletions(-) create mode 100644 BlazorApp2/wwwroot/appsettings.json rename src/{Contrib/Globalization/Masa.Contrib.Globalization.I18N => BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N}/Options/I18NOptions.cs (91%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Blazor => Masa.Contrib.Globalization.I18N.BlazorServer}/Extensions/ApplicationBuilderExtensions.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Blazor => Masa.Contrib.Globalization.I18N.BlazorServer/Extensions}/ServiceCollectionExtensions.cs (76%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Blazor => Masa.Contrib.Globalization.I18N.BlazorServer}/I18NOfT.cs (80%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj => Masa.Contrib.Globalization.I18N.BlazorServer/Masa.Contrib.Globalization.I18N.BlazorServer.csproj} (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Blazor => Masa.Contrib.Globalization.I18N.BlazorServer}/_Imports.cs (100%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs diff --git a/BlazorApp2/wwwroot/appsettings.json b/BlazorApp2/wwwroot/appsettings.json new file mode 100644 index 000000000..7b9079580 --- /dev/null +++ b/BlazorApp2/wwwroot/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Name": "test" +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs index edc3f497b..5a7a0cc86 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.BuildingBlocks.Globalization.I18N; @@ -39,6 +39,21 @@ public bool TryAdd(Type resourceType, Action action, params Type[] return true; } + public Task TryAddAsync(Func func, params Type[] baseResourceTypes) + { + return TryAddAsync(typeof(TResource), func, baseResourceTypes); + } + + public async Task TryAddAsync(Type resourceType, Func func, params Type[] baseResourceTypes) + { + if (this.ContainsKey(resourceType)) + return false; + + var i18NResource = Add(resourceType, baseResourceTypes); + await func.Invoke(i18NResource); + return true; + } + public I18NResource? GetOrNull(Type resourceType) { if (!ContainsKey(resourceType)) diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs similarity index 91% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs index 5a880b654..2f3ac6132 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Options/I18NOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18N; public class I18NOptions { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index b51383891..2a68c5323 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -1,5 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Globalization.I18N; +global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Options; global using System.Globalization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ApplicationBuilderExtensions.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Extensions/ApplicationBuilderExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ApplicationBuilderExtensions.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs similarity index 76% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs index 9b7ca29b0..7a696e655 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace @@ -7,10 +7,10 @@ namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { - public static IServiceCollection AddI18NForBlazor(this IServiceCollection services, Action? action = null) + public static IServiceCollection AddI18NForBlazorServer(this IServiceCollection services, Action? action = null) { services.AddHttpContextAccessor(); - services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.Blazor.I18N<>)); + services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.BlazorServer.I18NOfT<>)); services.TryAddScoped(); services.AddI18N(setting => { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/I18NOfT.cs similarity index 80% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/I18NOfT.cs index e62889d1c..27c3dff1c 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/I18NOfT.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/I18NOfT.cs @@ -1,10 +1,10 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Blazor; +namespace Masa.Contrib.Globalization.I18N.BlazorServer; [ExcludeFromCodeCoverage] -public class I18N : I18NOfT +public class I18NOfT : BuildingBlocks.Globalization.I18N.I18NOfT { private const string CULTURE_COOKIE_KEY = ".AspNetCore.Culture"; @@ -15,16 +15,16 @@ public class I18N : I18NOfT private readonly IHttpContextAccessor _httpContextAccessor; private readonly IOptions _options; - public I18N(IJSRuntime jsRuntime, IHttpContextAccessor httpContextAccessor, IOptions options) + public I18NOfT(IJSRuntime jsRuntime, IHttpContextAccessor httpContextAccessor, IOptions options) { _jsRuntime = jsRuntime; _httpContextAccessor = httpContextAccessor; _options = options; } - public override CultureInfo GetCultureInfo() => GetSelectCulture().Culture; + public override CultureInfo GetCultureInfo() => CultureInfo.CurrentCulture; - public override CultureInfo GetUiCultureInfo() => GetSelectCulture().UICulture; + public override CultureInfo GetUiCultureInfo() => CultureInfo.CurrentUICulture; public override void SetCulture(CultureInfo culture) => SetCultureCore(culture, GetUiCultureInfo()); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Masa.Contrib.Globalization.I18N.BlazorServer.csproj similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/Masa.Contrib.Globalization.I18N.Blazor.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Masa.Contrib.Globalization.I18N.BlazorServer.csproj diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs index 11a677b53..1618c5463 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Blazor/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs @@ -3,10 +3,10 @@ global using Masa.BuildingBlocks.Globalization.I18N; global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Localization; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.Extensions.Options; global using Microsoft.JSInterop; global using System.Diagnostics.CodeAnalysis; global using System.Globalization; +global using Microsoft.AspNetCore.Localization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs new file mode 100644 index 000000000..9e406da65 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs @@ -0,0 +1,133 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.BuildingBlocks.Globalization.I18N; + +public static class I18NResourceExtensions +{ + private static IConfiguration? _configuration; + + private static IMasaConfiguration? _masaConfiguration; + + public static Task AddJsonAsync( + this I18NResource resource, + string baseAddress, + string resourcePath, + params CultureModel[] supportedCultures) + => resource.AddJsonAsync(baseAddress, resourcePath, supportedCultures.ToList()); + + public static async Task AddJsonAsync( + this I18NResource resource, + string baseAddress, + string resourcePath, + IEnumerable supportedCultures) + { + var resourceContributors = await GetResourceContributorsAsync( + resource, + baseAddress, + resourcePath, + supportedCultures); + foreach (var resourceContributor in resourceContributors) + { + resource.AddContributor(resourceContributor.CultureName, resourceContributor); + } + return resource; + } + + private static async Task> GetResourceContributorsAsync( + I18NResource resource, + string baseAddress, + string resourcePath, + IEnumerable supportedCultures) + { + _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); + _masaConfiguration ??= + MasaApp.GetServices().BuildServiceProvider().GetService(); + + var services = MasaApp.GetServices(); + var useMasaConfiguration = _masaConfiguration != null; + var configuration = await AddJsonConfigurationSourceAsync( + services, + baseAddress, + resourcePath, + supportedCultures, + resource.ResourceType, + _configuration, + useMasaConfiguration); + _configuration = configuration; + + return supportedCultures.Select(supportedCulture => (II18NResourceContributor)new LocalI18NResourceContributor + ( + resource.ResourceType, + supportedCulture.Culture, + useMasaConfiguration ? _configuration.GetSection(SectionTypes.Local.ToString()) : _configuration! + ) + ) + .ToList(); + } + + private static async Task AddJsonConfigurationSourceAsync( + IServiceCollection services, + string baseAddress, + string resourcePath, + IEnumerable supportedCultures, + Type resourceType, + IConfiguration? configuration, + bool useMasaConfiguration) + { + ConfigurationManager configurationManager = new(); + if (configuration == null) + { + configuration = configurationManager; + services.AddSingleton(configurationManager); + } + else if (configuration is not ConfigurationManager) + { + configurationManager.AddConfiguration(configuration); + } + else if (configuration is ConfigurationManager configurationManagerTemp) + { + configurationManager = configurationManagerTemp; + } + var configurationBuilder = new ConfigurationBuilder(); + var httpClient = new HttpClient() + { + BaseAddress = new Uri(baseAddress) + }; + var dictionary = new Dictionary(); + foreach (var culture in supportedCultures) + { + var memoryStream = await GetStreamAsync(httpClient, resourcePath, culture.Culture); + if (memoryStream != null) + dictionary.Add(culture.Culture, memoryStream); + } + var jsonLocalizationConfigurationSource = + new Contrib.Globalization.I18N.BlazorWebAssembly.Json.JsonConfigurationSource( + resourceType, + dictionary, + useMasaConfiguration); + configurationBuilder.Add(jsonLocalizationConfigurationSource); + var localizationConfiguration = configurationBuilder.Build(); + configurationManager.AddConfiguration(localizationConfiguration); + return configuration; + } + + private static async Task GetStreamAsync(HttpClient httpClient, string languageDirectory, string cultureName) + { + Stream? stream = null; + try + { + string fileName = Path.Combine(languageDirectory, $"{cultureName}.json"); + Console.WriteLine("fileName: " + fileName); + var jsonByteArray = await httpClient.GetByteArrayAsync(fileName); + stream = new MemoryStream(jsonByteArray); + } + catch (Exception ex) + { + //todo: + } + return stream; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..c3aa39304 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,79 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.Extensions.DependencyInjection; + +public static class ServiceCollectionExtensions +{ + public static Task AddI18NForBlazorWebAssemblyAsync( + this IServiceCollection services, + string baseAddress, + Action? action = null) + => services.AddI18NForBlazorWebAssemblyAsync(settings => + { + settings.ResourcesDirectory = baseAddress; + }, action); + + public static Task AddI18NForBlazorWebAssemblyAsync( + this IServiceCollection services, + Action settingsAction, + Action? action = null) + { + services.AddOptions(); + services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.BlazorWebAssembly.I18NOfT<>)); + services.TryAddScoped(); + + MasaApp.TrySetServiceCollection(services); + return services.AddI18NForBlazorWebAssemblyCoreAsync(settingsAction, action); + } + + private static async Task AddI18NForBlazorWebAssemblyCoreAsync( + this IServiceCollection services, + Action? settingsAction, + Action? action = null) + { + services.AddOptions(); + services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.BlazorWebAssembly.I18NOfT<>)); + + var languageSettings = await GetCultureSettingsAsync(settingsAction); + services.AddSingleton(Microsoft.Extensions.Options.Options.Create(languageSettings)); + + services.TryAddSingleton(); + + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); + + var serviceProvider = services.BuildServiceProvider(); + + await I18NResourceResourceConfiguration.Resources.TryAddAsync(async resource + => await resource.AddJsonAsync(languageSettings.ResourcesDirectory!, BlazorWebAssemblyConstant.DefaultResourcePath, + languageSettings.SupportedCultures)); + action?.Invoke(new I18NOptions(services, languageSettings.SupportedCultures)); + + var i18N = serviceProvider.GetRequiredService(); + CultureInfo.CurrentCulture = i18N.GetCultureInfo(); + CultureInfo.CurrentUICulture = i18N.GetUiCultureInfo(); + return services; + } + + private static async Task GetCultureSettingsAsync(Action? settingsAction) + { + var cultureSettings = new CultureSettings(); + settingsAction?.Invoke(cultureSettings); + + ArgumentNullException.ThrowIfNull(cultureSettings.ResourcesDirectory); + + if (string.IsNullOrWhiteSpace(cultureSettings.SupportCultureName)) + cultureSettings.SupportCultureName = BlazorWebAssemblyConstant.SUPPORTED_CULTURES_NAME; + + if (!cultureSettings.SupportedCultures.Any()) + cultureSettings.SupportedCultures = await CultureUtils + .GetSupportedCulturesAsync(cultureSettings.ResourcesDirectory!, BlazorWebAssemblyConstant.DefaultResourcePath, + cultureSettings.SupportCultureName); + + if (string.IsNullOrEmpty(cultureSettings.DefaultCulture)) + cultureSettings.DefaultCulture = cultureSettings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; + return cultureSettings; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs new file mode 100644 index 000000000..7d0a122b2 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs @@ -0,0 +1,15 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Extensions; + +public static class WebAssemblyHostBuilderExtensions +{ + public static async Task AddI18NForBlazorWebAssemblyAsync( + this WebAssemblyHostBuilder builder, + Action? action = null) + { + await builder.Services.AddI18NForBlazorWebAssemblyAsync(builder.HostEnvironment.BaseAddress, action); + return builder; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs new file mode 100644 index 000000000..27b0d98d2 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs @@ -0,0 +1,55 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly; + +[ExcludeFromCodeCoverage] +public class I18NOfT : BuildingBlocks.Globalization.I18N.I18NOfT +{ + private const string CULTURE_COOKIE_KEY = ".AspNetCore.Culture"; + + private const string UI_CULTURE_COOKIE_KEY = ".AspNetCore.UICulture"; + + private const string GET_COOKIE_JS = @"(function(name){ + return window.localStorage[name]; + })"; + + private const string SET_COOKIE_JS = @"(function(name, value){ + return window.localStorage[name] = value; + })"; + + private readonly IJSInProcessRuntime _jsRuntime; + private readonly IOptions _options; + + public I18NOfT(IJSRuntime jsRuntime, IOptions options) + { + _jsRuntime = (IJSInProcessRuntime)jsRuntime; + _options = options; + } + + public override CultureInfo GetCultureInfo() => GetSelectCulture(CULTURE_COOKIE_KEY); + + public override CultureInfo GetUiCultureInfo() => GetSelectCulture(UI_CULTURE_COOKIE_KEY); + + public override void SetCulture(CultureInfo culture) + => SetCultureCore(CULTURE_COOKIE_KEY, culture); + + public override void SetUiCulture(CultureInfo culture) => SetCultureCore(UI_CULTURE_COOKIE_KEY, culture); + + private CultureInfo GetSelectCulture(string name) + { + var result = _jsRuntime.Invoke("eval", $"{GET_COOKIE_JS}('{name}')"); + return new(result ?? _options.Value.DefaultCulture); + } + + private void SetCultureCore(string name, CultureInfo culture) + { + try + { + _jsRuntime.InvokeVoidAsync("eval", $"{SET_COOKIE_JS}('{name}','{culture.Name}')"); + } + catch (Exception ex) + { + } + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs new file mode 100644 index 000000000..07f4a2395 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs @@ -0,0 +1,27 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly; + +internal static class Constant +{ + internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; + + internal static readonly string DefaultResourcePath; + + internal static readonly string DefaultFrameworkResourcePath; + + internal static readonly string DefaultFrameworkExceptionResourcePath; + + internal static readonly string DefaultFrameworkLanguageResourcePath; + + static Constant() + { + DefaultResourcePath = Path.Combine("Resources", "I18n"); + DefaultFrameworkResourcePath = Path.Combine(DefaultResourcePath, "Framework"); + DefaultFrameworkExceptionResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Exceptions"); + DefaultFrameworkLanguageResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Languages"); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs new file mode 100644 index 000000000..81d4c371d --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs @@ -0,0 +1,38 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly; + +public static class CultureUtils +{ + public static async Task> GetSupportedCulturesAsync( + string baseAddress, + string resourcePath, + string supportCultureName) + { + var http = new HttpClient() + { + BaseAddress = new Uri(baseAddress) + }; + List? supportedCultures = null; + try + { + var fileName = Path.Combine(resourcePath, supportCultureName); + supportedCultures = await http.GetFromJsonAsync>($"{fileName}"); + } + catch (Exception ex) + { + //todo: + } + finally + { + supportedCultures ??= new List() + { + new("en-us", "English") + }; + } + return supportedCultures; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs new file mode 100644 index 000000000..68781501a --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs @@ -0,0 +1,74 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Json; + +public class JsonConfigurationProvider : ConfigurationProvider +{ + private readonly string _resourceType; + private readonly bool _useMasaConfiguration; + private readonly Dictionary _data; + private readonly Dictionary> _dictionary; + + public JsonConfigurationProvider(JsonConfigurationSource configurationSource) + { + _resourceType = configurationSource.ResourceType.Name; + _data = configurationSource.Data; + _useMasaConfiguration = configurationSource.UseMasaConfiguration; + _dictionary = new(StringComparer.OrdinalIgnoreCase); + } + + public override void Load() + { + foreach (var item in _data) + { + _dictionary[FormatKey(item.Key)] = InitializeConfiguration(item.Value).ConvertToDictionary(); + } + + Data = FormatData(); + } + + private string FormatKey(string cultureName) + { + string localSection = BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION; + var list = _useMasaConfiguration ? + new List + { + SectionTypes.Local.ToString(), + localSection, + _resourceType, + cultureName + } : + new List + { + localSection, + _resourceType, + cultureName + }; + return string.Join(ConfigurationPath.KeyDelimiter, list); + } + + private IConfiguration InitializeConfiguration(Stream stream) + { + var configurationBuilder = new ConfigurationBuilder(); + var source = new JsonStreamConfigurationSource + { + Stream = stream + }; + configurationBuilder.Sources.Add(source); + return configurationBuilder.Build(); + } + + private Dictionary FormatData() + { + var data = new Dictionary(); + foreach (var item in _dictionary) + { + foreach (var resource in item.Value) + { + data[$"{item.Key}{ConfigurationPath.KeyDelimiter}{resource.Key}"] = resource.Value; + } + } + return data; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs new file mode 100644 index 000000000..826c09e21 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs @@ -0,0 +1,29 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Json; + +public class JsonConfigurationSource : IConfigurationSource +{ + public Type ResourceType { get; } + + public Dictionary Data { get; } + + public bool UseMasaConfiguration { get; } + + public JsonConfigurationSource( + Type resourceType, + Dictionary data, + bool useMasaConfiguration) + { + ResourceType = resourceType; + Data = data; + UseMasaConfiguration = useMasaConfiguration; + } + + public IConfigurationProvider Build(IConfigurationBuilder builder) + { + var configurationProvider = new JsonConfigurationProvider(this); + return configurationProvider; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs new file mode 100644 index 000000000..b28521d3a --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs @@ -0,0 +1,41 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.Extensions.Localization; + +public class LocalI18NResourceContributor : II18NResourceContributor +{ + /// + /// Random number for handling special keys. + /// + private static readonly string _randomNumber = Guid.NewGuid().ToString(); + + private readonly IConfiguration _configuration; + + public Type ResourceType { get; } + + public string CultureName { get; } + + public LocalI18NResourceContributor( + Type resourceType, + string cultureName, + IConfiguration configuration) + { + ResourceType = resourceType; + CultureName = cultureName; + _configuration = configuration; + } + + public string? GetOrNull(string name) + { + var section = _configuration.GetSection(Masa.BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); + if (section != null && section.Exists()) + { + string newName = name.Replace("\\.", _randomNumber).Replace(".", ConfigurationPath.KeyDelimiter).Replace(_randomNumber, "."); + return section.GetValue(newName); + } + return null; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj new file mode 100644 index 000000000..6e43b0905 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj @@ -0,0 +1,19 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs new file mode 100644 index 000000000..7de3ddccf --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs @@ -0,0 +1,19 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Data; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.DependencyInjection.Extensions; +global using Microsoft.Extensions.Options; +global using Microsoft.JSInterop; +global using System.Diagnostics.CodeAnalysis; +global using System.Globalization; +global using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +global using Masa.Contrib.Globalization.I18N.BlazorWebAssembly; +global using BlazorWebAssemblyConstant = Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Constant; +global using System.Net.Http.Json; +global using Microsoft.Extensions.Configuration.Json; +global using Microsoft.Extensions.Localization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index caccbc0bb..6da922688 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace @@ -13,7 +13,6 @@ public static IServiceCollection AddI18N( string? supportCultureName = null, Action? action = null) { - MasaArgumentException.ThrowIfNullOrWhiteSpace(languageDirectory); return services.AddI18N(settings => { settings.ResourcesDirectory = languageDirectory; @@ -40,7 +39,6 @@ public static IServiceCollection TestAddI18N( string? supportCultureName = null, Action? action = null) { - MasaArgumentException.ThrowIfNullOrWhiteSpace(languageDirectory); return services.TestAddI18N(settings => { settings.ResourcesDirectory = languageDirectory; @@ -93,7 +91,7 @@ private static IServiceCollection AddI18NCore( if (localLanguageSettings == null) { var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); - localLanguageSettings = serviceProvider.GetService>()!.Value; + localLanguageSettings = serviceProvider.GetService>()?.Value ?? new CultureSettings(); languageSettings ??= localLanguageSettings; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs index 0265004f8..8e86cfa24 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Globalization.I18N.Internal; @@ -10,7 +10,7 @@ public static List GetSupportedCultures( string supportCultureName) { int retry = 0; - start: + start: try { var fileName = Path.Combine(languageDirectory, supportCultureName); @@ -36,6 +36,11 @@ public static List GetSupportedCultures( } catch (IOException ex) { + return new List() + { + new("en-us", "English") + }; + retry++; if (retry <= 10) { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index 1c13d0a5a..290d415a8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -8,7 +8,6 @@ - @@ -19,9 +18,11 @@ - - Always - + + + + + diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj index 70399a08e..e9bc0a0d2 100644 --- a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj +++ b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj @@ -1,20 +1,18 @@ - - net6.0 - Masa.Contrib.Globalization.I18N.zh_CN - enable - enable - + + net6.0 + Masa.Contrib.Globalization.I18N.zh_CN + enable + enable + - - - Always - - + + + - - - + + + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj index 6b6440e75..707428599 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj @@ -16,13 +16,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + - + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs index 79494554f..d1247c95d 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Globalization.I18N.Blazor.Tests; @@ -10,8 +10,8 @@ public class ServicesCollectionsTest public void TestAddI18NForBlazor() { var services = new ServiceCollection(); - services.AddI18NForBlazor(); - var descriptor = ServiceDescriptor.Transient(typeof(II18N<>), typeof(I18N<>)); + services.AddI18NForBlazorServer(); + var descriptor = ServiceDescriptor.Transient(typeof(II18N<>), typeof(I18NOfT<>)); Assert.IsTrue(services.Any(d => d.ServiceType == descriptor.ServiceType && d.Lifetime == descriptor.Lifetime && d.ImplementationType == descriptor.ImplementationType)); From 3a0b87bf48bc7a1ac723c7564f4a938ea3bbb90d Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Tue, 8 Nov 2022 22:31:25 +0800 Subject: [PATCH 24/38] feat(I18n): Adjust I18n Support Embedded resources --- .../Extensions/ServiceCollectionExtensions.cs | 2 +- .../_Imports.cs | 1 + .../{Internal => }/Constant.cs | 10 +- .../EmbeddedResourceUtils.cs | 52 ++++++++ .../Extensions/I18NResourceExtensions.cs | 111 ++++++++++++++++-- .../Extensions/ServiceCollectionExtensions.cs | 29 +++-- .../FileConfigurationProvider.cs | 8 +- .../Internal/CultureUtils.cs | 5 - .../JsonConfigurationProviderByEmbedded.cs | 70 +++++++++++ .../Json/JsonConfigurationSourceByEmbedded.cs | 33 ++++++ .../Masa.Contrib.Globalization.I18N.csproj | 4 - .../_Imports.cs | 3 +- 12 files changed, 287 insertions(+), 41 deletions(-) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/{Internal => }/Constant.cs (72%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs index 7a696e655..53f06253f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs @@ -17,7 +17,7 @@ public static IServiceCollection AddI18NForBlazorServer(this IServiceCollection action?.Invoke(setting); if (setting.ResourcesDirectory.IsNullOrWhiteSpace()) - setting.ResourcesDirectory = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, "Resources", "I18n"); + setting.ResourcesDirectory = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, "wwwroot", ContribI18NConstant.DefaultResourcePath); }); return services; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs index 1618c5463..10ad747a7 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs @@ -10,3 +10,4 @@ global using System.Diagnostics.CodeAnalysis; global using System.Globalization; global using Microsoft.AspNetCore.Localization; +global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs similarity index 72% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs index e4efdae3a..a8efdaa78 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs @@ -1,13 +1,13 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Internal; +namespace Masa.Contrib.Globalization.I18N; -internal static class Constant +public static class Constant { - internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; + public const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; - internal static readonly string DefaultResourcePath; + public static readonly string DefaultResourcePath; internal static readonly string DefaultFrameworkResourcePath; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs new file mode 100644 index 000000000..bc1c4f889 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs @@ -0,0 +1,52 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N; + +public class EmbeddedResourceUtils +{ + private readonly List> _list; + + public EmbeddedResourceUtils(params Assembly[] assemblies) : this(assemblies.ToList()) + { + } + + public EmbeddedResourceUtils(IEnumerable assemblies) + { + _list = assemblies + .Select(assembly => new KeyValuePair(assembly, assembly.GetManifestResourceNames())) + .ToList(); + } + + public List> GetResources(string resourcesDirectory) + { + var list = new List>(); + foreach (var item in _list) + { + var data = item.Value.Where(resourceName + => resourceName.IndexOf(FormatResourcesDirectory(resourcesDirectory), StringComparison.OrdinalIgnoreCase) > 0).ToArray(); + if (data.Length > 0) + { + list.Add(new KeyValuePair(item.Key, data)); + } + } + return list; + } + + public Stream? GetStream(Assembly assembly, string fileName) => assembly.GetManifestResourceStream(fileName); + + public string? GetCulture(string resourcesDirectory, string fileName) + { + var formatResourcesDirectory = FormatResourcesDirectory(resourcesDirectory); + var index = fileName.IndexOf(formatResourcesDirectory, StringComparison.OrdinalIgnoreCase); + if (index >= 0) + return fileName.Substring(index).Replace(formatResourcesDirectory + ".", "").Replace(".json", ""); + + return null; + } + + private string FormatResourcesDirectory(string resourcesDirectory) + { + return resourcesDirectory.Replace("\\", "."); + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index e59b4cc27..c6d7ca5c5 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -28,7 +28,33 @@ public static I18NResource AddJson( var resourceContributors = GetResourceContributors( resource, resourcesDirectory, - supportedCultures); + supportedCultures, + Array.Empty()); + foreach (var resourceContributor in resourceContributors) + { + resource.AddContributor(resourceContributor.CultureName, resourceContributor); + } + return resource; + } + + public static I18NResource AddJson( + this I18NResource resource, + IEnumerable assemblies, + string resourcesDirectory, + params CultureModel[] supportedCultures) + => resource.AddJson(assemblies, resourcesDirectory, supportedCultures.ToList()); + + public static I18NResource AddJson( + this I18NResource resource, + IEnumerable assemblies, + string resourcesDirectory, + IEnumerable supportedCultures) + { + var resourceContributors = GetResourceContributors( + resource, + resourcesDirectory, + supportedCultures, + assemblies); foreach (var resourceContributor in resourceContributors) { resource.AddContributor(resourceContributor.CultureName, resourceContributor); @@ -39,7 +65,8 @@ public static I18NResource AddJson( private static List GetResourceContributors( I18NResource resource, string resourcesDirectory, - IEnumerable supportedCultures) + IEnumerable supportedCultures, + IEnumerable assemblies) { _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); _masaConfiguration ??= @@ -47,13 +74,21 @@ private static List GetResourceContributors( var services = MasaApp.GetServices(); var useMasaConfiguration = _masaConfiguration != null; - var configuration = AddJsonConfigurationSource( - services, - resourcesDirectory, - supportedCultures, - resource.ResourceType, - _configuration, - useMasaConfiguration); + var configuration = !assemblies.Any() ? AddJsonConfigurationSource( + services, + resourcesDirectory, + supportedCultures, + resource.ResourceType, + _configuration, + useMasaConfiguration) : + AddJsonConfigurationSourceByEmbeddedResource( + assemblies, + services, + resourcesDirectory, + supportedCultures, + resource.ResourceType, + _configuration, + useMasaConfiguration); _configuration = configuration; return supportedCultures.Select(supportedCulture => (II18NResourceContributor)new LocalI18NResourceContributor @@ -73,6 +108,53 @@ private static IConfiguration AddJsonConfigurationSource( Type resourceType, IConfiguration? configuration, bool useMasaConfiguration) + { + return AddJsonConfigurationSourceCore( + services, + configuration, + () => new List() + { + new JsonConfigurationSource(resourceType, resourcesDirectory, supportedCultures.Select(c => c.Culture), + useMasaConfiguration) + }); + } + + private static IConfiguration AddJsonConfigurationSourceByEmbeddedResource( + IEnumerable assemblies, + IServiceCollection services, + string resourcesDirectory, + IEnumerable supportedCultures, + Type resourceType, + IConfiguration? configuration, + bool useMasaConfiguration) + { + return AddJsonConfigurationSourceCore(services, + configuration, + () => + { + var list = new List(); + var embeddedResourceUtils = new EmbeddedResourceUtils(assemblies); + var resourceData = embeddedResourceUtils.GetResources(resourcesDirectory); + foreach (var item in resourceData) + { + foreach (var fileName in item.Value) + { + var stream = embeddedResourceUtils.GetStream(item.Key, fileName); + if (stream == null) continue; + + var culture = embeddedResourceUtils.GetCulture(resourcesDirectory, fileName); + if (culture != null && supportedCultures.Any(cul => cul.Culture.Equals(culture, StringComparison.OrdinalIgnoreCase))) + list.Add(new JsonConfigurationSourceByEmbedded(resourceType, stream, culture, useMasaConfiguration)); + } + } + return list; + }); + } + + private static IConfiguration AddJsonConfigurationSourceCore( + IServiceCollection services, + IConfiguration? configuration, + Func> func) { ConfigurationManager configurationManager = new(); if (configuration == null) @@ -89,10 +171,13 @@ private static IConfiguration AddJsonConfigurationSource( configurationManager = configurationManagerTemp; } var configurationBuilder = new ConfigurationBuilder(); - var jsonLocalizationConfigurationSource = - new JsonConfigurationSource(resourceType, resourcesDirectory, supportedCultures.Select(c => c.Culture), - useMasaConfiguration); - configurationBuilder.Add(jsonLocalizationConfigurationSource); + + var jsonLocalizationConfigurationSources = func.Invoke(); + foreach (var source in jsonLocalizationConfigurationSources) + { + configurationBuilder.Add(source); + } + var localizationConfiguration = configurationBuilder.Build(); configurationManager.AddConfiguration(localizationConfiguration); return configuration; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index 6da922688..177038cf4 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -16,7 +16,8 @@ public static IServiceCollection AddI18N( return services.AddI18N(settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? Constant.SUPPORTED_CULTURES_NAME : supportCultureName; + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : + supportCultureName; settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); if (string.IsNullOrEmpty(settings.DefaultCulture)) @@ -42,7 +43,8 @@ public static IServiceCollection TestAddI18N( return services.TestAddI18N(settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? Constant.SUPPORTED_CULTURES_NAME : supportCultureName; + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : + supportCultureName; settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); if (string.IsNullOrEmpty(settings.DefaultCulture)) @@ -71,10 +73,10 @@ private static IServiceCollection AddI18NCore( settingsAction?.Invoke(settings); if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) - settings.ResourcesDirectory = Constant.DefaultResourcePath; + settings.ResourcesDirectory = ContribI18NConstant.DefaultResourcePath; if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) - settings.SupportCultureName = Constant.SUPPORTED_CULTURES_NAME; + settings.SupportCultureName = ContribI18NConstant.SUPPORTED_CULTURES_NAME; if (!settings.SupportedCultures.Any()) settings.SupportedCultures = @@ -95,17 +97,28 @@ private static IServiceCollection AddI18NCore( languageSettings ??= localLanguageSettings; } + var assembly = typeof(EmbeddedResourceUtils).Assembly; + options.Resources.TryAdd(resource - => resource.AddJson(Constant.DefaultFrameworkResourcePath, localLanguageSettings.SupportedCultures)); + => resource.AddJson(new List() + { + assembly + }, ContribI18NConstant.DefaultFrameworkResourcePath, localLanguageSettings.SupportedCultures)); options.Resources.TryAdd(resource - => resource.AddJson(Constant.DefaultFrameworkExceptionResourcePath, localLanguageSettings.SupportedCultures)); + => resource.AddJson(new List() + { + assembly + }, ContribI18NConstant.DefaultFrameworkExceptionResourcePath, localLanguageSettings.SupportedCultures)); options.Resources.TryAdd(resource - => resource.AddJson(Constant.DefaultFrameworkLanguageResourcePath, localLanguageSettings.SupportedCultures)); + => resource.AddJson(new List() + { + assembly + }, ContribI18NConstant.DefaultFrameworkLanguageResourcePath, localLanguageSettings.SupportedCultures)); options.Resources.TryAdd(resource - => resource.AddJson(localLanguageSettings.ResourcesDirectory ?? Constant.DefaultResourcePath, + => resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, localLanguageSettings.SupportedCultures)); }); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs index f28ed4750..7db348aad 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs @@ -5,7 +5,7 @@ namespace Masa.Contrib.Globalization.I18N; public abstract class FileConfigurationProvider : ConfigurationProvider { - private readonly string _resourceType; + private readonly string _resourceTypeName; private readonly string _languageDirectory; private readonly IEnumerable _cultureNames; private readonly bool _useMasaConfiguration; @@ -13,7 +13,7 @@ public abstract class FileConfigurationProvider : ConfigurationProvider protected FileConfigurationProvider(JsonConfigurationSource configurationSource) { - _resourceType = configurationSource.ResourceType.Name; + _resourceTypeName = configurationSource.ResourceType.Name; _languageDirectory = configurationSource.LanguageDirectory; _cultureNames = configurationSource.CultureNames; _useMasaConfiguration = configurationSource.UseMasaConfiguration; @@ -39,13 +39,13 @@ private string FormatKey(string cultureName) { SectionTypes.Local.ToString(), localSection, - _resourceType, + _resourceTypeName, cultureName } : new List { localSection, - _resourceType, + _resourceTypeName, cultureName }; return string.Join(ConfigurationPath.KeyDelimiter, list); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs index 8e86cfa24..dfe5a0b5b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs @@ -36,11 +36,6 @@ public static List GetSupportedCultures( } catch (IOException ex) { - return new List() - { - new("en-us", "English") - }; - retry++; if (retry <= 10) { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs new file mode 100644 index 000000000..6e8a0f41f --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs @@ -0,0 +1,70 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +using Microsoft.Extensions.Configuration.Json; + +namespace Masa.Contrib.Globalization.I18N.Json; + +public class JsonConfigurationProviderByEmbedded : ConfigurationProvider +{ + private readonly string _resourceTypeName; + private readonly Stream _stream; + private readonly bool _useMasaConfiguration; + private readonly string _culture; + private Dictionary _dictionary; + private readonly ConfigurationBuilder _configurationBuilder; + private readonly string _prefix; + + public JsonConfigurationProviderByEmbedded(JsonConfigurationSourceByEmbedded sourceByEmbedded) + { + _resourceTypeName = sourceByEmbedded.ResourceType.Name; + _stream = sourceByEmbedded.Stream; + _useMasaConfiguration = sourceByEmbedded.UseMasaConfiguration; + _culture = sourceByEmbedded.Culture; + _dictionary = new(StringComparer.OrdinalIgnoreCase); + _configurationBuilder = new ConfigurationBuilder(); + _prefix = FormatKey(_culture); + } + + public override void Load() + { + var configuration = new JsonStreamConfigurationSource() + { + Stream = _stream + }; + _configurationBuilder.Add(configuration); + _dictionary = _configurationBuilder.Build().ConvertToDictionary(); + + Data = FormatData(); + } + + private string FormatKey(string cultureName) + { + string localSection = BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION; + var list = _useMasaConfiguration ? + new List + { + SectionTypes.Local.ToString(), + localSection, + _resourceTypeName, + cultureName + } : + new List + { + localSection, + _resourceTypeName, + cultureName + }; + return string.Join(ConfigurationPath.KeyDelimiter, list); + } + + private Dictionary FormatData() + { + var data = new Dictionary(); + foreach (var resource in _dictionary) + { + data[$"{_prefix}{ConfigurationPath.KeyDelimiter}{resource.Key}"] = resource.Value; + } + return data; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs new file mode 100644 index 000000000..591189cbe --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Json; + +public class JsonConfigurationSourceByEmbedded : IConfigurationSource +{ + public Type ResourceType { get; } + + public string Culture { get; } + + public Stream Stream { get; } + + public bool UseMasaConfiguration { get; } + + public JsonConfigurationSourceByEmbedded( + Type resourceType, + Stream stream, + string culture, + bool useMasaConfiguration) + { + ResourceType = resourceType; + Stream = stream; + Culture = culture; + UseMasaConfiguration = useMasaConfiguration; + } + + public IConfigurationProvider Build(IConfigurationBuilder builder) + { + var configurationProvider = new JsonConfigurationProviderByEmbedded(this); + return configurationProvider; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index 290d415a8..ef039112e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -21,8 +21,4 @@ - - - - diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index 5af5325d7..cfb84d4a1 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -13,4 +13,5 @@ global using Microsoft.Extensions.Localization; global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; -global using Constant = Masa.Contrib.Globalization.I18N.Internal.Constant; +global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; +global using System.Reflection; From 377306443063b97acba01d98f7ce4e9918663876 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 9 Nov 2022 12:00:08 +0800 Subject: [PATCH 25/38] feat: Caller Support I18N --- .../I18NResource.cs | 2 + .../_Imports.cs | 2 +- .../ApplicationBuilderExtensions.cs | 33 ---- .../Extensions/ServiceCollectionExtensions.cs | 24 --- .../I18NOfT.cs | 54 ------- ...rib.Globalization.I18N.BlazorServer.csproj | 18 --- .../_Imports.cs | 13 -- .../Extensions/I18NResourceExtensions.cs | 133 --------------- .../Extensions/ServiceCollectionExtensions.cs | 79 --------- .../WebAssemblyHostBuilderExtensions.cs | 15 -- .../I18NOfT.cs | 55 ------- .../Internal/Constant.cs | 27 ---- .../Internal/CultureUtils.cs | 38 ----- .../Json/JsonConfigurationProvider.cs | 74 --------- .../Json/JsonConfigurationSource.cs | 29 ---- .../LocalI18NResourceContributor.cs | 41 ----- ...lobalization.I18N.BlazorWebAssembly.csproj | 19 --- .../_Imports.cs | 19 --- .../Extensions/I18NResourceExtensions.cs | 43 ++--- .../Extensions/ServiceCollectionExtensions.cs | 151 +++++++++++------- .../I18n/Framework/Exceptions/zh-CN.json | 0 .../I18n/Framework/Languages/zh-CN.json | 0 ...sa.Contrib.Globalization.I18N.zh-CN.csproj | 18 --- ...rib.Globalization.I18N.Blazor.Tests.csproj | 4 - .../DefaultRequestMessage.cs | 23 +++ .../JsonRequestMessage.cs | 1 + .../XmlRequestMessage.cs | 1 + 27 files changed, 138 insertions(+), 778 deletions(-) delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ApplicationBuilderExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/I18NOfT.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Masa.Contrib.Globalization.I18N.BlazorServer.csproj delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs rename src/Contrib/Globalization/{Resources/Masa.Contrib.Globalization.I18N.zh-CN => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/Exceptions/zh-CN.json (100%) rename src/Contrib/Globalization/{Resources/Masa.Contrib.Globalization.I18N.zh-CN => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/Languages/zh-CN.json (100%) delete mode 100644 src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs index 6b03c3b73..0d0976408 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs @@ -11,6 +11,8 @@ public class I18NResource public IEnumerable BaseResourceTypes { get; } + public IEnumerable Assemblies { get; set; } = new List(); + public I18NResource(Type resourceType, IEnumerable baseResourceTypes) { _dictionary = new(StringComparer.OrdinalIgnoreCase); diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index 2a68c5323..1ec7d0dd4 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.BuildingBlocks.Globalization.I18N; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Options; global using System.Globalization; +global using System.Reflection; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ApplicationBuilderExtensions.cs deleted file mode 100644 index 162f294b8..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ApplicationBuilderExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Microsoft.AspNetCore.Builder; - -public static class ApplicationBuilderExtensions -{ - private static bool _isInitialize; - - public static IApplicationBuilder UseI18N(this IApplicationBuilder app) - { - if (_isInitialize) - return app; - - _isInitialize = true; - var settings = app.ApplicationServices.GetRequiredService>().Value; - - var requestLocalization = new RequestLocalizationOptions(); - - var cultures = settings.SupportedCultures.Select(x => x.Culture).ToArray(); - requestLocalization - .AddSupportedCultures(cultures) - .AddSupportedUICultures(cultures); - if (!string.IsNullOrWhiteSpace(settings.DefaultCulture)) - requestLocalization.SetDefaultCulture(settings.DefaultCulture); - - requestLocalization.ApplyCurrentCultureToResponseHeaders = true; - app.UseRequestLocalization(requestLocalization); - return app; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs deleted file mode 100644 index 53f06253f..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Extensions/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Microsoft.Extensions.DependencyInjection; - -public static class ServiceCollectionExtensions -{ - public static IServiceCollection AddI18NForBlazorServer(this IServiceCollection services, Action? action = null) - { - services.AddHttpContextAccessor(); - services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.BlazorServer.I18NOfT<>)); - services.TryAddScoped(); - services.AddI18N(setting => - { - action?.Invoke(setting); - - if (setting.ResourcesDirectory.IsNullOrWhiteSpace()) - setting.ResourcesDirectory = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, "wwwroot", ContribI18NConstant.DefaultResourcePath); - }); - return services; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/I18NOfT.cs deleted file mode 100644 index 27c3dff1c..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/I18NOfT.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N.BlazorServer; - -[ExcludeFromCodeCoverage] -public class I18NOfT : BuildingBlocks.Globalization.I18N.I18NOfT -{ - private const string CULTURE_COOKIE_KEY = ".AspNetCore.Culture"; - - private const string SET_COOKIE_JS = - "(function(name,value){ var Days = 30;var exp = new Date();exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);document.cookie = `${name}=${escape(value.toString())};path=/;expires=${exp.toUTCString()}`;})"; - - private readonly IJSRuntime _jsRuntime; - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly IOptions _options; - - public I18NOfT(IJSRuntime jsRuntime, IHttpContextAccessor httpContextAccessor, IOptions options) - { - _jsRuntime = jsRuntime; - _httpContextAccessor = httpContextAccessor; - _options = options; - } - - public override CultureInfo GetCultureInfo() => CultureInfo.CurrentCulture; - - public override CultureInfo GetUiCultureInfo() => CultureInfo.CurrentUICulture; - - public override void SetCulture(CultureInfo culture) - => SetCultureCore(culture, GetUiCultureInfo()); - - public override void SetUiCulture(CultureInfo culture) => SetCultureCore(GetCultureInfo(), culture); - - private RequestCulture GetSelectCulture() - { - var httpContext = _httpContextAccessor.HttpContext; - if (httpContext == null) return new RequestCulture(_options.Value.DefaultCulture); - - var requestCulture = httpContext.Features.Get(); - return requestCulture?.RequestCulture ?? new RequestCulture(_options.Value.DefaultCulture); - } - - private void SetCultureCore(CultureInfo culture, CultureInfo uiCulture) - { - try - { - var val = ($"c={culture.Name}|uic={uiCulture.Name}"); - _jsRuntime.InvokeVoidAsync("eval", $"{SET_COOKIE_JS}('{CULTURE_COOKIE_KEY}','{val}')"); - } - catch (Exception ex) - { - } - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Masa.Contrib.Globalization.I18N.BlazorServer.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Masa.Contrib.Globalization.I18N.BlazorServer.csproj deleted file mode 100644 index 38f145211..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/Masa.Contrib.Globalization.I18N.BlazorServer.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - - diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs deleted file mode 100644 index 10ad747a7..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorServer/_Imports.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -global using Masa.BuildingBlocks.Globalization.I18N; -global using Microsoft.AspNetCore.Http; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.DependencyInjection.Extensions; -global using Microsoft.Extensions.Options; -global using Microsoft.JSInterop; -global using System.Diagnostics.CodeAnalysis; -global using System.Globalization; -global using Microsoft.AspNetCore.Localization; -global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs deleted file mode 100644 index 9e406da65..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/I18NResourceExtensions.cs +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Masa.BuildingBlocks.Globalization.I18N; - -public static class I18NResourceExtensions -{ - private static IConfiguration? _configuration; - - private static IMasaConfiguration? _masaConfiguration; - - public static Task AddJsonAsync( - this I18NResource resource, - string baseAddress, - string resourcePath, - params CultureModel[] supportedCultures) - => resource.AddJsonAsync(baseAddress, resourcePath, supportedCultures.ToList()); - - public static async Task AddJsonAsync( - this I18NResource resource, - string baseAddress, - string resourcePath, - IEnumerable supportedCultures) - { - var resourceContributors = await GetResourceContributorsAsync( - resource, - baseAddress, - resourcePath, - supportedCultures); - foreach (var resourceContributor in resourceContributors) - { - resource.AddContributor(resourceContributor.CultureName, resourceContributor); - } - return resource; - } - - private static async Task> GetResourceContributorsAsync( - I18NResource resource, - string baseAddress, - string resourcePath, - IEnumerable supportedCultures) - { - _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); - _masaConfiguration ??= - MasaApp.GetServices().BuildServiceProvider().GetService(); - - var services = MasaApp.GetServices(); - var useMasaConfiguration = _masaConfiguration != null; - var configuration = await AddJsonConfigurationSourceAsync( - services, - baseAddress, - resourcePath, - supportedCultures, - resource.ResourceType, - _configuration, - useMasaConfiguration); - _configuration = configuration; - - return supportedCultures.Select(supportedCulture => (II18NResourceContributor)new LocalI18NResourceContributor - ( - resource.ResourceType, - supportedCulture.Culture, - useMasaConfiguration ? _configuration.GetSection(SectionTypes.Local.ToString()) : _configuration! - ) - ) - .ToList(); - } - - private static async Task AddJsonConfigurationSourceAsync( - IServiceCollection services, - string baseAddress, - string resourcePath, - IEnumerable supportedCultures, - Type resourceType, - IConfiguration? configuration, - bool useMasaConfiguration) - { - ConfigurationManager configurationManager = new(); - if (configuration == null) - { - configuration = configurationManager; - services.AddSingleton(configurationManager); - } - else if (configuration is not ConfigurationManager) - { - configurationManager.AddConfiguration(configuration); - } - else if (configuration is ConfigurationManager configurationManagerTemp) - { - configurationManager = configurationManagerTemp; - } - var configurationBuilder = new ConfigurationBuilder(); - var httpClient = new HttpClient() - { - BaseAddress = new Uri(baseAddress) - }; - var dictionary = new Dictionary(); - foreach (var culture in supportedCultures) - { - var memoryStream = await GetStreamAsync(httpClient, resourcePath, culture.Culture); - if (memoryStream != null) - dictionary.Add(culture.Culture, memoryStream); - } - var jsonLocalizationConfigurationSource = - new Contrib.Globalization.I18N.BlazorWebAssembly.Json.JsonConfigurationSource( - resourceType, - dictionary, - useMasaConfiguration); - configurationBuilder.Add(jsonLocalizationConfigurationSource); - var localizationConfiguration = configurationBuilder.Build(); - configurationManager.AddConfiguration(localizationConfiguration); - return configuration; - } - - private static async Task GetStreamAsync(HttpClient httpClient, string languageDirectory, string cultureName) - { - Stream? stream = null; - try - { - string fileName = Path.Combine(languageDirectory, $"{cultureName}.json"); - Console.WriteLine("fileName: " + fileName); - var jsonByteArray = await httpClient.GetByteArrayAsync(fileName); - stream = new MemoryStream(jsonByteArray); - } - catch (Exception ex) - { - //todo: - } - return stream; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs deleted file mode 100644 index c3aa39304..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Microsoft.Extensions.DependencyInjection; - -public static class ServiceCollectionExtensions -{ - public static Task AddI18NForBlazorWebAssemblyAsync( - this IServiceCollection services, - string baseAddress, - Action? action = null) - => services.AddI18NForBlazorWebAssemblyAsync(settings => - { - settings.ResourcesDirectory = baseAddress; - }, action); - - public static Task AddI18NForBlazorWebAssemblyAsync( - this IServiceCollection services, - Action settingsAction, - Action? action = null) - { - services.AddOptions(); - services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.BlazorWebAssembly.I18NOfT<>)); - services.TryAddScoped(); - - MasaApp.TrySetServiceCollection(services); - return services.AddI18NForBlazorWebAssemblyCoreAsync(settingsAction, action); - } - - private static async Task AddI18NForBlazorWebAssemblyCoreAsync( - this IServiceCollection services, - Action? settingsAction, - Action? action = null) - { - services.AddOptions(); - services.TryAddTransient(typeof(II18N<>), typeof(Masa.Contrib.Globalization.I18N.BlazorWebAssembly.I18NOfT<>)); - - var languageSettings = await GetCultureSettingsAsync(settingsAction); - services.AddSingleton(Microsoft.Extensions.Options.Options.Create(languageSettings)); - - services.TryAddSingleton(); - - services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); - - var serviceProvider = services.BuildServiceProvider(); - - await I18NResourceResourceConfiguration.Resources.TryAddAsync(async resource - => await resource.AddJsonAsync(languageSettings.ResourcesDirectory!, BlazorWebAssemblyConstant.DefaultResourcePath, - languageSettings.SupportedCultures)); - action?.Invoke(new I18NOptions(services, languageSettings.SupportedCultures)); - - var i18N = serviceProvider.GetRequiredService(); - CultureInfo.CurrentCulture = i18N.GetCultureInfo(); - CultureInfo.CurrentUICulture = i18N.GetUiCultureInfo(); - return services; - } - - private static async Task GetCultureSettingsAsync(Action? settingsAction) - { - var cultureSettings = new CultureSettings(); - settingsAction?.Invoke(cultureSettings); - - ArgumentNullException.ThrowIfNull(cultureSettings.ResourcesDirectory); - - if (string.IsNullOrWhiteSpace(cultureSettings.SupportCultureName)) - cultureSettings.SupportCultureName = BlazorWebAssemblyConstant.SUPPORTED_CULTURES_NAME; - - if (!cultureSettings.SupportedCultures.Any()) - cultureSettings.SupportedCultures = await CultureUtils - .GetSupportedCulturesAsync(cultureSettings.ResourcesDirectory!, BlazorWebAssemblyConstant.DefaultResourcePath, - cultureSettings.SupportCultureName); - - if (string.IsNullOrEmpty(cultureSettings.DefaultCulture)) - cultureSettings.DefaultCulture = cultureSettings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; - return cultureSettings; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs deleted file mode 100644 index 7d0a122b2..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Extensions/WebAssemblyHostBuilderExtensions.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Extensions; - -public static class WebAssemblyHostBuilderExtensions -{ - public static async Task AddI18NForBlazorWebAssemblyAsync( - this WebAssemblyHostBuilder builder, - Action? action = null) - { - await builder.Services.AddI18NForBlazorWebAssemblyAsync(builder.HostEnvironment.BaseAddress, action); - return builder; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs deleted file mode 100644 index 27b0d98d2..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/I18NOfT.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly; - -[ExcludeFromCodeCoverage] -public class I18NOfT : BuildingBlocks.Globalization.I18N.I18NOfT -{ - private const string CULTURE_COOKIE_KEY = ".AspNetCore.Culture"; - - private const string UI_CULTURE_COOKIE_KEY = ".AspNetCore.UICulture"; - - private const string GET_COOKIE_JS = @"(function(name){ - return window.localStorage[name]; - })"; - - private const string SET_COOKIE_JS = @"(function(name, value){ - return window.localStorage[name] = value; - })"; - - private readonly IJSInProcessRuntime _jsRuntime; - private readonly IOptions _options; - - public I18NOfT(IJSRuntime jsRuntime, IOptions options) - { - _jsRuntime = (IJSInProcessRuntime)jsRuntime; - _options = options; - } - - public override CultureInfo GetCultureInfo() => GetSelectCulture(CULTURE_COOKIE_KEY); - - public override CultureInfo GetUiCultureInfo() => GetSelectCulture(UI_CULTURE_COOKIE_KEY); - - public override void SetCulture(CultureInfo culture) - => SetCultureCore(CULTURE_COOKIE_KEY, culture); - - public override void SetUiCulture(CultureInfo culture) => SetCultureCore(UI_CULTURE_COOKIE_KEY, culture); - - private CultureInfo GetSelectCulture(string name) - { - var result = _jsRuntime.Invoke("eval", $"{GET_COOKIE_JS}('{name}')"); - return new(result ?? _options.Value.DefaultCulture); - } - - private void SetCultureCore(string name, CultureInfo culture) - { - try - { - _jsRuntime.InvokeVoidAsync("eval", $"{SET_COOKIE_JS}('{name}','{culture.Name}')"); - } - catch (Exception ex) - { - } - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs deleted file mode 100644 index 07f4a2395..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/Constant.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly; - -internal static class Constant -{ - internal const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; - - internal static readonly string DefaultResourcePath; - - internal static readonly string DefaultFrameworkResourcePath; - - internal static readonly string DefaultFrameworkExceptionResourcePath; - - internal static readonly string DefaultFrameworkLanguageResourcePath; - - static Constant() - { - DefaultResourcePath = Path.Combine("Resources", "I18n"); - DefaultFrameworkResourcePath = Path.Combine(DefaultResourcePath, "Framework"); - DefaultFrameworkExceptionResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Exceptions"); - DefaultFrameworkLanguageResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Languages"); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs deleted file mode 100644 index 81d4c371d..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Internal/CultureUtils.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly; - -public static class CultureUtils -{ - public static async Task> GetSupportedCulturesAsync( - string baseAddress, - string resourcePath, - string supportCultureName) - { - var http = new HttpClient() - { - BaseAddress = new Uri(baseAddress) - }; - List? supportedCultures = null; - try - { - var fileName = Path.Combine(resourcePath, supportCultureName); - supportedCultures = await http.GetFromJsonAsync>($"{fileName}"); - } - catch (Exception ex) - { - //todo: - } - finally - { - supportedCultures ??= new List() - { - new("en-us", "English") - }; - } - return supportedCultures; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs deleted file mode 100644 index 68781501a..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationProvider.cs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Json; - -public class JsonConfigurationProvider : ConfigurationProvider -{ - private readonly string _resourceType; - private readonly bool _useMasaConfiguration; - private readonly Dictionary _data; - private readonly Dictionary> _dictionary; - - public JsonConfigurationProvider(JsonConfigurationSource configurationSource) - { - _resourceType = configurationSource.ResourceType.Name; - _data = configurationSource.Data; - _useMasaConfiguration = configurationSource.UseMasaConfiguration; - _dictionary = new(StringComparer.OrdinalIgnoreCase); - } - - public override void Load() - { - foreach (var item in _data) - { - _dictionary[FormatKey(item.Key)] = InitializeConfiguration(item.Value).ConvertToDictionary(); - } - - Data = FormatData(); - } - - private string FormatKey(string cultureName) - { - string localSection = BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION; - var list = _useMasaConfiguration ? - new List - { - SectionTypes.Local.ToString(), - localSection, - _resourceType, - cultureName - } : - new List - { - localSection, - _resourceType, - cultureName - }; - return string.Join(ConfigurationPath.KeyDelimiter, list); - } - - private IConfiguration InitializeConfiguration(Stream stream) - { - var configurationBuilder = new ConfigurationBuilder(); - var source = new JsonStreamConfigurationSource - { - Stream = stream - }; - configurationBuilder.Sources.Add(source); - return configurationBuilder.Build(); - } - - private Dictionary FormatData() - { - var data = new Dictionary(); - foreach (var item in _dictionary) - { - foreach (var resource in item.Value) - { - data[$"{item.Key}{ConfigurationPath.KeyDelimiter}{resource.Key}"] = resource.Value; - } - } - return data; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs deleted file mode 100644 index 826c09e21..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Json/JsonConfigurationSource.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Json; - -public class JsonConfigurationSource : IConfigurationSource -{ - public Type ResourceType { get; } - - public Dictionary Data { get; } - - public bool UseMasaConfiguration { get; } - - public JsonConfigurationSource( - Type resourceType, - Dictionary data, - bool useMasaConfiguration) - { - ResourceType = resourceType; - Data = data; - UseMasaConfiguration = useMasaConfiguration; - } - - public IConfigurationProvider Build(IConfigurationBuilder builder) - { - var configurationProvider = new JsonConfigurationProvider(this); - return configurationProvider; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs deleted file mode 100644 index b28521d3a..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/LocalI18NResourceContributor.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -// ReSharper disable once CheckNamespace - -namespace Microsoft.Extensions.Localization; - -public class LocalI18NResourceContributor : II18NResourceContributor -{ - /// - /// Random number for handling special keys. - /// - private static readonly string _randomNumber = Guid.NewGuid().ToString(); - - private readonly IConfiguration _configuration; - - public Type ResourceType { get; } - - public string CultureName { get; } - - public LocalI18NResourceContributor( - Type resourceType, - string cultureName, - IConfiguration configuration) - { - ResourceType = resourceType; - CultureName = cultureName; - _configuration = configuration; - } - - public string? GetOrNull(string name) - { - var section = _configuration.GetSection(Masa.BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); - if (section != null && section.Exists()) - { - string newName = name.Replace("\\.", _randomNumber).Replace(".", ConfigurationPath.KeyDelimiter).Replace(_randomNumber, "."); - return section.GetValue(newName); - } - return null; - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj deleted file mode 100644 index 6e43b0905..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/Masa.Contrib.Globalization.I18N.BlazorWebAssembly.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - - - diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs deleted file mode 100644 index 7de3ddccf..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.BlazorWebAssembly/_Imports.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -global using Masa.BuildingBlocks.Globalization.I18N; -global using Masa.BuildingBlocks.Configuration; -global using Masa.BuildingBlocks.Data; -global using Microsoft.Extensions.Configuration; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.DependencyInjection.Extensions; -global using Microsoft.Extensions.Options; -global using Microsoft.JSInterop; -global using System.Diagnostics.CodeAnalysis; -global using System.Globalization; -global using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -global using Masa.Contrib.Globalization.I18N.BlazorWebAssembly; -global using BlazorWebAssemblyConstant = Masa.Contrib.Globalization.I18N.BlazorWebAssembly.Constant; -global using System.Net.Http.Json; -global using Microsoft.Extensions.Configuration.Json; -global using Microsoft.Extensions.Localization; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index c6d7ca5c5..e8ea74351 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -11,50 +11,41 @@ public static class I18NResourceExtensions private static IMasaConfiguration? _masaConfiguration; - public static I18NResource AddJson( + public static I18NResource AddJsonByEmbeddedResource( this I18NResource resource, + IEnumerable assemblies, string resourcesDirectory, params CultureModel[] supportedCultures) - => resource.AddJson(resourcesDirectory, supportedCultures.ToList()); + => resource.AddJsonByEmbeddedResource(assemblies, resourcesDirectory, supportedCultures.ToList()); - public static I18NResource AddJson( + public static I18NResource AddJsonByEmbeddedResource( this I18NResource resource, + IEnumerable assemblies, string resourcesDirectory, IEnumerable supportedCultures) { - if (!PathUtils.ParseResourcesDirectory(ref resourcesDirectory)) - return resource; - - var resourceContributors = GetResourceContributors( - resource, - resourcesDirectory, - supportedCultures, - Array.Empty()); - foreach (var resourceContributor in resourceContributors) - { - resource.AddContributor(resourceContributor.CultureName, resourceContributor); - } - return resource; + resource.Assemblies = assemblies; + return resource.AddJson(resourcesDirectory, supportedCultures); } public static I18NResource AddJson( this I18NResource resource, - IEnumerable assemblies, string resourcesDirectory, params CultureModel[] supportedCultures) - => resource.AddJson(assemblies, resourcesDirectory, supportedCultures.ToList()); + => resource.AddJson(resourcesDirectory, supportedCultures.ToList()); public static I18NResource AddJson( this I18NResource resource, - IEnumerable assemblies, string resourcesDirectory, IEnumerable supportedCultures) { + if (!resource.Assemblies.Any() && !PathUtils.ParseResourcesDirectory(ref resourcesDirectory)) + return resource; + var resourceContributors = GetResourceContributors( resource, resourcesDirectory, - supportedCultures, - assemblies); + supportedCultures); foreach (var resourceContributor in resourceContributors) { resource.AddContributor(resourceContributor.CultureName, resourceContributor); @@ -65,8 +56,7 @@ public static I18NResource AddJson( private static List GetResourceContributors( I18NResource resource, string resourcesDirectory, - IEnumerable supportedCultures, - IEnumerable assemblies) + IEnumerable supportedCultures) { _configuration ??= MasaApp.GetServices().BuildServiceProvider().GetService(); _masaConfiguration ??= @@ -74,7 +64,7 @@ private static List GetResourceContributors( var services = MasaApp.GetServices(); var useMasaConfiguration = _masaConfiguration != null; - var configuration = !assemblies.Any() ? AddJsonConfigurationSource( + var configuration = !resource.Assemblies.Any() ? AddJsonConfigurationSource( services, resourcesDirectory, supportedCultures, @@ -82,7 +72,7 @@ private static List GetResourceContributors( _configuration, useMasaConfiguration) : AddJsonConfigurationSourceByEmbeddedResource( - assemblies, + resource.Assemblies, services, resourcesDirectory, supportedCultures, @@ -143,7 +133,8 @@ private static IConfiguration AddJsonConfigurationSourceByEmbeddedResource( if (stream == null) continue; var culture = embeddedResourceUtils.GetCulture(resourcesDirectory, fileName); - if (culture != null && supportedCultures.Any(cul => cul.Culture.Equals(culture, StringComparison.OrdinalIgnoreCase))) + if (culture != null && + supportedCultures.Any(cul => cul.Culture.Equals(culture, StringComparison.OrdinalIgnoreCase))) list.Add(new JsonConfigurationSourceByEmbedded(resourceType, stream, culture, useMasaConfiguration)); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index 177038cf4..3945aa338 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -12,26 +12,42 @@ public static IServiceCollection AddI18N( string languageDirectory, string? supportCultureName = null, Action? action = null) - { - return services.AddI18N(settings => - { - settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : - supportCultureName; - settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); + => services.AddI18NByEmbedded(Array.Empty(), languageDirectory, supportCultureName, action); - if (string.IsNullOrEmpty(settings.DefaultCulture)) - settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; - }, action); + public static IServiceCollection AddI18N( + this IServiceCollection services, + Action? settingsAction = null, + Action? action = null) + => services.AddI18NByEmbedded(Array.Empty(), settingsAction, action); + + public static IServiceCollection AddI18NByEmbedded( + this IServiceCollection services, + IEnumerable assemblies, + string languageDirectory, + string? supportCultureName = null, + Action? action = null) + { + return services.AddI18NByEmbedded(assemblies, + settings => + { + settings.ResourcesDirectory = languageDirectory; + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : + supportCultureName; + }, action); } - public static IServiceCollection AddI18N( + public static IServiceCollection AddI18NByEmbedded( this IServiceCollection services, + IEnumerable assemblies, Action? settingsAction = null, Action? action = null) { MasaApp.TrySetServiceCollection(services); - return services.AddI18NCore(settingsAction, action); + + var cultureSettings = AddAndGetCultureSettings(services, settingsAction); + return services + .AddI18NByFramework(cultureSettings) + .AddI18NCore(action, assemblies, cultureSettings); } public static IServiceCollection TestAddI18N( @@ -58,16 +74,45 @@ public static IServiceCollection TestAddI18N( Action? action = null) { MasaApp.SetServiceCollection(services); - return services.AddI18NCore(settingsAction, action); + var cultureSettings = AddAndGetCultureSettings(services, settingsAction); + return services + .AddI18NByFramework(cultureSettings) + .AddI18NCore(action, Array.Empty(), cultureSettings); } - private static IServiceCollection AddI18NCore( + private static IServiceCollection AddI18NByFramework(this IServiceCollection services, CultureSettings languageSettings) + { + services.Configure(options => + { + var assembly = typeof(EmbeddedResourceUtils).Assembly; + options.Resources.TryAdd(resource => + { + resource.AddJsonByEmbeddedResource(new[] { assembly }, + languageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, + languageSettings.SupportedCultures); + }); + + options.Resources.TryAdd(resource => + { + resource.AddJsonByEmbeddedResource(new[] { assembly }, + ContribI18NConstant.DefaultFrameworkExceptionResourcePath, + languageSettings.SupportedCultures); + }); + + options.Resources.TryAdd(resource => + { + resource.AddJsonByEmbeddedResource(new[] { assembly }, + ContribI18NConstant.DefaultFrameworkLanguageResourcePath, + languageSettings.SupportedCultures); + }); + }); + return services; + } + + private static CultureSettings AddAndGetCultureSettings( this IServiceCollection services, - Action? settingsAction, - Action? action = null) + Action? settingsAction) { - services.AddOptions(); - services.TryAddTransient(typeof(II18N<>), typeof(I18NOfT<>)); services.Configure(settings => { settingsAction?.Invoke(settings); @@ -85,57 +130,47 @@ private static IServiceCollection AddI18NCore( if (string.IsNullOrEmpty(settings.DefaultCulture)) settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; }); + var serviceProvider = services.BuildServiceProvider(); + return serviceProvider.GetRequiredService>().Value; + } + + private static IServiceCollection AddI18NCore( + this IServiceCollection services, + Action? action, + IEnumerable assemblies, + CultureSettings cultureSettings) where TResource : class + { + services.AddOptions(); + services.TryAddTransient(typeof(II18N<>), typeof(I18NOfT<>)); + services.TryAddSingleton(); + services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); - CultureSettings? languageSettings = null; services.Configure(options => { - var localLanguageSettings = languageSettings; - if (localLanguageSettings == null) + var localLanguageSettings = cultureSettings; + options.Resources.TryAdd(resource => { - var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); - localLanguageSettings = serviceProvider.GetService>()?.Value ?? new CultureSettings(); - languageSettings ??= localLanguageSettings; - } - - var assembly = typeof(EmbeddedResourceUtils).Assembly; - - options.Resources.TryAdd(resource - => resource.AddJson(new List() + if (!assemblies.Any()) { - assembly - }, ContribI18NConstant.DefaultFrameworkResourcePath, localLanguageSettings.SupportedCultures)); - - options.Resources.TryAdd(resource - => resource.AddJson(new List() - { - assembly - }, ContribI18NConstant.DefaultFrameworkExceptionResourcePath, localLanguageSettings.SupportedCultures)); - - options.Resources.TryAdd(resource - => resource.AddJson(new List() + resource.AddJson( + localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, + localLanguageSettings.SupportedCultures); + } + else { - assembly - }, ContribI18NConstant.DefaultFrameworkLanguageResourcePath, localLanguageSettings.SupportedCultures)); - - options.Resources.TryAdd(resource - => resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, - localLanguageSettings.SupportedCultures)); + resource.AddJsonByEmbeddedResource(assemblies, + localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, + localLanguageSettings.SupportedCultures); + } + }); }); - services.TryAddSingleton(); - - services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); + action?.Invoke(new I18NOptions(services, cultureSettings.SupportedCultures)); - var serviceProvider = services.BuildServiceProvider(); - if (action != null) - { - languageSettings = serviceProvider.GetRequiredService>().Value; - action.Invoke(new I18NOptions(services, languageSettings.SupportedCultures)); - } - - var i18NOptions = serviceProvider.GetRequiredService>(); + var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); foreach (var resource in i18NOptions.Value.Resources) I18NResourceResourceConfiguration.Resources[resource.Key] = resource.Value; + return services; } } diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Exceptions/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Exceptions/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/zh-CN.json diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Languages/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Resources/I18n/Framework/Languages/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json diff --git a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj b/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj deleted file mode 100644 index e9bc0a0d2..000000000 --- a/src/Contrib/Globalization/Resources/Masa.Contrib.Globalization.I18N.zh-CN/Masa.Contrib.Globalization.I18N.zh-CN.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net6.0 - Masa.Contrib.Globalization.I18N.zh_CN - enable - enable - - - - - - - - - - - diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj index 707428599..980919745 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj @@ -21,10 +21,6 @@ - - - - Always diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs index d1167e92e..475cd4cff 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +using System.Globalization; + namespace Masa.Contrib.Service.Caller; public abstract class DefaultRequestMessage @@ -31,4 +33,25 @@ protected virtual void TrySetRequestId(HttpRequestMessage requestMessage) if (requestMessage.Headers.All(h => h.Key != _requestIdKey)) requestMessage.Headers.Add(_requestIdKey, requestId.ToString()); } + + protected virtual void TrySetCulture(HttpRequestMessage requestMessage) + { + var cultures = new List<(string Key, string Value)> + { + ("c", CultureInfo.CurrentCulture.Name), + ("uic", CultureInfo.CurrentUICulture.Name) + }; + TrySetCulture(requestMessage, cultures); + } + + protected virtual void TrySetCulture(HttpRequestMessage requestMessage, List<(string Key, string Value)> cultures) + { + var name = "cookie"; + if (requestMessage.Headers.TryGetValues(name, out IEnumerable? cookieValues)) + requestMessage.Headers.Remove(name); + string value = System.Web.HttpUtility.UrlEncode(string.Join('|', cultures.Select(c => $"{c.Key}={c.Value}"))); + var cookies = cookieValues?.ToList() ?? new List(); + cookies.Add($".AspNetCore.Culture={value}"); + requestMessage.Headers.Add(name, cookies); + } } diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/JsonRequestMessage.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/JsonRequestMessage.cs index 3a4c698ac..8e5942756 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/JsonRequestMessage.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/JsonRequestMessage.cs @@ -18,6 +18,7 @@ public JsonRequestMessage( public virtual Task ProcessHttpRequestMessageAsync(HttpRequestMessage requestMessage) { TrySetRequestId(requestMessage); + TrySetCulture(requestMessage); return Task.FromResult(requestMessage); } diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/XmlRequestMessage.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/XmlRequestMessage.cs index 5790aa200..7c366cd73 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/XmlRequestMessage.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/XmlRequestMessage.cs @@ -15,6 +15,7 @@ public XmlRequestMessage( public Task ProcessHttpRequestMessageAsync(HttpRequestMessage requestMessage) { TrySetRequestId(requestMessage); + TrySetCulture(requestMessage); return Task.FromResult(requestMessage); } From dc4d3e62462379d00179da9ad625df51d7fdb044 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 9 Nov 2022 18:14:25 +0800 Subject: [PATCH 26/38] feat: Support FluentValidation --- BlazorApp2/wwwroot/appsettings.json | 10 - Masa.Framework.sln | 214 ++++++++---------- .../Constants/ErrorCode.cs | 209 +++++++++++++---- .../MasaArgumentExceptionTest.cs | 4 +- .../MasaArgumentException.cs | 55 ++--- .../MasaException.cs | 13 +- .../MasaHttpStatusCode.cs | 4 + .../MasaValidatorException.cs | 211 +++++++++++++++++ .../ValidationLevel.cs | 15 ++ .../ValidationModel.cs | 27 +++ .../I18N.cs | 80 +++++++ .../Resources/DefaultResource.cs | 1 + .../Resources/MasaFrameworkResource.cs | 2 +- .../Resources/MasaLanguageResource.cs | 2 +- ....cs => MasaParameterValidationResource.cs} | 2 +- .../_Imports.cs | 1 + ....Dispatcher.Events.FluentValidation.csproj | 17 ++ .../Middleware/ValidatorMiddleware.cs | 45 ++++ .../_Imports.cs | 6 + .../ApplicationBuilderExtensions.cs | 5 +- .../Handlers/ExceptionHandlerMiddleware.cs | 2 +- .../Handlers/MvcGlobalExceptionFilter.cs | 2 +- .../Internal/ExceptionExtensions.cs | 3 + .../Constant.cs | 4 +- .../EmbeddedResourceUtils.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 6 +- .../Masa.Contrib.Globalization.I18N.csproj | 1 + .../I18n/Framework/Exceptions/en-US.json | 15 -- .../I18n/Framework/Exceptions/zh-CN.json | 15 -- .../Framework/ParameterValidations/en-US.json | 34 +++ .../Framework/ParameterValidations/zh-CN.json | 34 +++ .../Resources/I18n/Framework/en-US.json | 3 + .../Resources/I18n/Framework/zh-CN.json | 3 + ...rib.Globalization.I18N.Blazor.Tests.csproj | 36 --- .../Resources/i18n/en-US.json | 6 - .../Resources/i18n/supportedCultures.json | 10 - .../Resources/i18n/zh-CN.json | 6 - .../ServicesCollectionsTest.cs | 19 -- .../_Imports.cs | 6 - .../DefaultResponseMessage.cs | 137 +++++------ 40 files changed, 854 insertions(+), 413 deletions(-) delete mode 100644 BlazorApp2/wwwroot/appsettings.json create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationLevel.cs create mode 100644 src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationModel.cs create mode 100644 src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs rename src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/{MasaExceptionResource.cs => MasaParameterValidationResource.cs} (87%) create mode 100644 src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Masa.Contrib.Dispatcher.Events.FluentValidation.csproj create mode 100644 src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs create mode 100644 src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/_Imports.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/en-US.json delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/zh-CN.json create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs delete mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs diff --git a/BlazorApp2/wwwroot/appsettings.json b/BlazorApp2/wwwroot/appsettings.json deleted file mode 100644 index 7b9079580..000000000 --- a/BlazorApp2/wwwroot/appsettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "Name": "test" -} diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 7dd65078d..8e7117fe1 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -17,10 +17,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution items", "solution .gitignore = .gitignore Directory.Build.props = Directory.Build.props LICENSE.txt = LICENSE.txt + Masa.Framework.sln.DotSettings = Masa.Framework.sln.DotSettings NuGet.Config = NuGet.Config README.md = README.md README.zh-CN.md = README.zh-CN.md - Masa.Framework.sln.DotSettings = Masa.Framework.sln.DotSettings EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E747043D-81E2-4A89-8B5B-1258ED45F941}" @@ -559,8 +559,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalizat EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalization", "{5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9}" EndProject -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.I18N", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18N\Masa.BuildingBlocks.Globalization.I18N.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Globalization.I18N", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18N\Masa.BuildingBlocks.Globalization.I18N.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A}" EndProject @@ -578,61 +577,53 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.RulesEn EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Development", "Development", "{43E0F1C0-7308-45C9-83CF-E6291ACE9F0F}" EndProject -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Development.DaprStarter", "src\BuildingBlocks\Development\Masa.BuildingBlocks.Development.DaprStarter\Masa.BuildingBlocks.Development.DaprStarter.csproj", "{77A9CADA-35D6-419B-87B3-AACC50FFAD0F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Development.DaprStarter", "src\BuildingBlocks\Development\Masa.BuildingBlocks.Development.DaprStarter\Masa.BuildingBlocks.Development.DaprStarter.csproj", "{77A9CADA-35D6-419B-87B3-AACC50FFAD0F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.RulesEngine.MicrosoftRulesEngine", "src\Contrib\RulesEngine\Masa.Contrib.RulesEngine.MicrosoftRulesEngine\Masa.Contrib.RulesEngine.MicrosoftRulesEngine.csproj", "{4E217EC9-0616-414B-82D9-9107F9826D6E}" EndProject -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Development.DaprStarter", "src\Contrib\Development\Masa.Contrib.Development.DaprStarter\Masa.Contrib.Development.DaprStarter.csproj", "{A6D4C293-E184-42C0-B9B7-3F856BE57EC0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.DaprStarter", "src\Contrib\Development\Masa.Contrib.Development.DaprStarter\Masa.Contrib.Development.DaprStarter.csproj", "{A6D4C293-E184-42C0-B9B7-3F856BE57EC0}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3FADF704-2581-47AC-A1F7-07091B6328A1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.RulesEngine.MicrosoftRulesEngine.Tests", "src\Contrib\RulesEngine\Tests\Masa.Contrib.RulesEngine.MicrosoftRulesEngine.Tests\Masa.Contrib.RulesEngine.MicrosoftRulesEngine.Tests.csproj", "{EEB2D542-5A2C-4E18-A0E6-72844C359DAD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Development.DaprStarter.AspNetCore", "src\Contrib\Development\Masa.Contrib.Development.DaprStarter.AspNetCore\Masa.Contrib.Development.DaprStarter.AspNetCore.csproj", "{E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.DaprStarter.AspNetCore", "src\Contrib\Development\Masa.Contrib.Development.DaprStarter.AspNetCore\Masa.Contrib.Development.DaprStarter.AspNetCore.csproj", "{E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dcc", "Dcc", "{5E0E61DA-06FF-4F08-9C76-0A8856C90EF5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.StackSdks.Dcc", "src\BuildingBlocks\StackSdks\Dcc\Masa.BuildingBlocks.StackSdks.Dcc\Masa.BuildingBlocks.StackSdks.Dcc.csproj", "{356C5F47-025F-4ED6-8E8A-8745E181C455}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.StackSdks.Dcc.Contracts", "src\BuildingBlocks\StackSdks\Dcc\Masa.BuildingBlocks.StackSdks.Dcc.Contracts\Masa.BuildingBlocks.StackSdks.Dcc.Contracts.csproj", "{C2E9EDAE-2558-4899-A486-917AE7A5D24F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.StackSdks.Dcc.Contracts", "src\BuildingBlocks\StackSdks\Dcc\Masa.BuildingBlocks.StackSdks.Dcc.Contracts\Masa.BuildingBlocks.StackSdks.Dcc.Contracts.csproj", "{C2E9EDAE-2558-4899-A486-917AE7A5D24F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8CDAF37E-3DB1-4573-B5AA-376C93A8D299}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Development.DaprStarter.Tests", "src\Contrib\Development\Tests\Masa.Contrib.Development.DaprStarter.Tests\Masa.Contrib.Development.DaprStarter.Tests.csproj", "{49B51B95-3DC5-45BD-B91A-3056FF5014B5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.DaprStarter.Tests", "src\Contrib\Development\Tests\Masa.Contrib.Development.DaprStarter.Tests\Masa.Contrib.Development.DaprStarter.Tests.csproj", "{49B51B95-3DC5-45BD-B91A-3056FF5014B5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Development.DaprStarter.AspNetCore.Tests", "src\Contrib\Development\Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests.csproj", "{DD899DC4-A2B7-4C7B-A644-EDB56A61145C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.DaprStarter.AspNetCore.Tests", "src\Contrib\Development\Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests.csproj", "{DD899DC4-A2B7-4C7B-A644-EDB56A61145C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N\Masa.Contrib.Globalization.I18N.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N\Masa.Contrib.Globalization.I18N.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D2E598D5-5E44-4275-AF03-4BAD07A0E13B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Tests\Masa.Contrib.Globalization.I18N.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Tests\Masa.Contrib.Globalization.I18N.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Dcc\Masa.Contrib.Globalization.I18N.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Dcc\Masa.Contrib.Globalization.I18N.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Blazor", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Blazor\Masa.Contrib.Globalization.I18N.Blazor.csproj", "{C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Blazor.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Blazor.Tests\Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj", "{EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exception", "Exception", "{84F366D3-6E9A-4101-AEC0-287CBA6984A8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exception", "Exception", "{F17FFB29-A622-4430-B2EA-E9FF20E68122}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Exceptions", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions\Masa.BuildingBlocks.Exceptions.csproj", "{145400E0-7AC3-4D7B-88D1-F17847E4FA6D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Exceptions", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions\Masa.BuildingBlocks.Exceptions.csproj", "{145400E0-7AC3-4D7B-88D1-F17847E4FA6D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Exceptions", "src\Contrib\Exception\Masa.Contrib.Exceptions\Masa.Contrib.Exceptions.csproj", "{C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Exceptions", "src\Contrib\Exception\Masa.Contrib.Exceptions\Masa.Contrib.Exceptions.csproj", "{C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Exceptions.Tests", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions.Tests\Masa.BuildingBlocks.Exceptions.Tests.csproj", "{921DCAAC-3146-4EDB-891C-D76089E4A451}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Exceptions.Tests", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions.Tests\Masa.BuildingBlocks.Exceptions.Tests.csproj", "{921DCAAC-3146-4EDB-891C-D76089E4A451}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.AspNetCore\Masa.Contrib.Globalization.I18N.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.AspNetCore\Masa.Contrib.Globalization.I18N.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resources", "Resources", "{95A0DD72-2C64-4C00-A201-94CD7E5BB3F4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Globalization.I18N.zh-CN", "src\Contrib\Globalization\Resources\Masa.Contrib.Globalization.I18N.zh-CN\Masa.Contrib.Globalization.I18N.zh-CN.csproj", "{EACF8A3A-13A9-4BAF-81B6-0C651993FC17}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Dispatcher.Events.FluentValidation", "src\Contrib\Dispatcher\Masa.Contrib.Dispatcher.Events.FluentValidation\Masa.Contrib.Dispatcher.Events.FluentValidation.csproj", "{66B1723A-D578-418C-B21C-2C3B5CBD1180}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -2034,14 +2025,6 @@ Global {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8}.Release|Any CPU.Build.0 = Release|Any CPU {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8}.Release|x64.ActiveCfg = Release|Any CPU {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8}.Release|x64.Build.0 = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.ActiveCfg = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.Build.0 = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.Build.0 = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.ActiveCfg = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.Build.0 = Release|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Debug|Any CPU.Build.0 = Debug|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2050,6 +2033,14 @@ Global {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Release|Any CPU.Build.0 = Release|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Release|x64.ActiveCfg = Release|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Release|x64.Build.0 = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.Build.0 = Debug|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.Build.0 = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.ActiveCfg = Release|Any CPU + {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.Build.0 = Release|Any CPU {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}.Debug|Any CPU.Build.0 = Debug|Any CPU {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2074,6 +2065,14 @@ Global {B03C329C-70F4-442A-B420-90DDF7E31847}.Release|Any CPU.Build.0 = Release|Any CPU {B03C329C-70F4-442A-B420-90DDF7E31847}.Release|x64.ActiveCfg = Release|Any CPU {B03C329C-70F4-442A-B420-90DDF7E31847}.Release|x64.Build.0 = Release|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|x64.ActiveCfg = Debug|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|x64.Build.0 = Debug|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|Any CPU.Build.0 = Release|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|x64.ActiveCfg = Release|Any CPU + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|x64.Build.0 = Release|Any CPU {4E217EC9-0616-414B-82D9-9107F9826D6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4E217EC9-0616-414B-82D9-9107F9826D6E}.Debug|Any CPU.Build.0 = Debug|Any CPU {4E217EC9-0616-414B-82D9-9107F9826D6E}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2082,6 +2081,14 @@ Global {4E217EC9-0616-414B-82D9-9107F9826D6E}.Release|Any CPU.Build.0 = Release|Any CPU {4E217EC9-0616-414B-82D9-9107F9826D6E}.Release|x64.ActiveCfg = Release|Any CPU {4E217EC9-0616-414B-82D9-9107F9826D6E}.Release|x64.Build.0 = Release|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|x64.ActiveCfg = Debug|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|x64.Build.0 = Debug|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|Any CPU.Build.0 = Release|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|x64.ActiveCfg = Release|Any CPU + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|x64.Build.0 = Release|Any CPU {EEB2D542-5A2C-4E18-A0E6-72844C359DAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EEB2D542-5A2C-4E18-A0E6-72844C359DAD}.Debug|Any CPU.Build.0 = Debug|Any CPU {EEB2D542-5A2C-4E18-A0E6-72844C359DAD}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2090,6 +2097,14 @@ Global {EEB2D542-5A2C-4E18-A0E6-72844C359DAD}.Release|Any CPU.Build.0 = Release|Any CPU {EEB2D542-5A2C-4E18-A0E6-72844C359DAD}.Release|x64.ActiveCfg = Release|Any CPU {EEB2D542-5A2C-4E18-A0E6-72844C359DAD}.Release|x64.Build.0 = Release|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|x64.ActiveCfg = Debug|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|x64.Build.0 = Debug|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|Any CPU.Build.0 = Release|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|x64.ActiveCfg = Release|Any CPU + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|x64.Build.0 = Release|Any CPU {356C5F47-025F-4ED6-8E8A-8745E181C455}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {356C5F47-025F-4ED6-8E8A-8745E181C455}.Debug|Any CPU.Build.0 = Debug|Any CPU {356C5F47-025F-4ED6-8E8A-8745E181C455}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2098,46 +2113,6 @@ Global {356C5F47-025F-4ED6-8E8A-8745E181C455}.Release|Any CPU.Build.0 = Release|Any CPU {356C5F47-025F-4ED6-8E8A-8745E181C455}.Release|x64.ActiveCfg = Release|Any CPU {356C5F47-025F-4ED6-8E8A-8745E181C455}.Release|x64.Build.0 = Release|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|x64.ActiveCfg = Debug|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|x64.Build.0 = Debug|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|Any CPU.Build.0 = Release|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.ActiveCfg = Release|Any CPU - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.Build.0 = Release|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|x64.ActiveCfg = Debug|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|x64.Build.0 = Debug|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Release|Any CPU.Build.0 = Release|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.ActiveCfg = Release|Any CPU - {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.Build.0 = Release|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|x64.ActiveCfg = Debug|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|x64.Build.0 = Debug|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|Any CPU.Build.0 = Release|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.ActiveCfg = Release|Any CPU - {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.Build.0 = Release|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|x64.ActiveCfg = Debug|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Debug|x64.Build.0 = Debug|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|Any CPU.Build.0 = Release|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|x64.ActiveCfg = Release|Any CPU - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB}.Release|x64.Build.0 = Release|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|x64.ActiveCfg = Debug|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Debug|x64.Build.0 = Debug|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|Any CPU.Build.0 = Release|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|x64.ActiveCfg = Release|Any CPU - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831}.Release|x64.Build.0 = Release|Any CPU {C2E9EDAE-2558-4899-A486-917AE7A5D24F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C2E9EDAE-2558-4899-A486-917AE7A5D24F}.Debug|Any CPU.Build.0 = Debug|Any CPU {C2E9EDAE-2558-4899-A486-917AE7A5D24F}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2146,30 +2121,6 @@ Global {C2E9EDAE-2558-4899-A486-917AE7A5D24F}.Release|Any CPU.Build.0 = Release|Any CPU {C2E9EDAE-2558-4899-A486-917AE7A5D24F}.Release|x64.ActiveCfg = Release|Any CPU {C2E9EDAE-2558-4899-A486-917AE7A5D24F}.Release|x64.Build.0 = Release|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|x64.ActiveCfg = Debug|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Debug|x64.Build.0 = Debug|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|Any CPU.Build.0 = Release|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|x64.ActiveCfg = Release|Any CPU - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F}.Release|x64.Build.0 = Release|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|x64.ActiveCfg = Debug|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Debug|x64.Build.0 = Debug|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|Any CPU.Build.0 = Release|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|x64.ActiveCfg = Release|Any CPU - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0}.Release|x64.Build.0 = Release|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|x64.ActiveCfg = Debug|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Debug|x64.Build.0 = Debug|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|Any CPU.Build.0 = Release|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|x64.ActiveCfg = Release|Any CPU - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA}.Release|x64.Build.0 = Release|Any CPU {49B51B95-3DC5-45BD-B91A-3056FF5014B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {49B51B95-3DC5-45BD-B91A-3056FF5014B5}.Debug|Any CPU.Build.0 = Debug|Any CPU {49B51B95-3DC5-45BD-B91A-3056FF5014B5}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2186,6 +2137,30 @@ Global {DD899DC4-A2B7-4C7B-A644-EDB56A61145C}.Release|Any CPU.Build.0 = Release|Any CPU {DD899DC4-A2B7-4C7B-A644-EDB56A61145C}.Release|x64.ActiveCfg = Release|Any CPU {DD899DC4-A2B7-4C7B-A644-EDB56A61145C}.Release|x64.Build.0 = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|x64.ActiveCfg = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Debug|x64.Build.0 = Debug|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|Any CPU.Build.0 = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.ActiveCfg = Release|Any CPU + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}.Release|x64.Build.0 = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|x64.ActiveCfg = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Debug|x64.Build.0 = Debug|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|Any CPU.Build.0 = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.ActiveCfg = Release|Any CPU + {6C732EBE-22CC-4160-B427-F4558C899024}.Release|x64.Build.0 = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|x64.ActiveCfg = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Debug|x64.Build.0 = Debug|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|Any CPU.Build.0 = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.ActiveCfg = Release|Any CPU + {B0EFDF9E-81FF-4880-992B-8A65A2008717}.Release|x64.Build.0 = Release|Any CPU {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Debug|Any CPU.Build.0 = Debug|Any CPU {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2226,14 +2201,14 @@ Global {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Release|Any CPU.Build.0 = Release|Any CPU {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Release|x64.ActiveCfg = Release|Any CPU {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}.Release|x64.Build.0 = Release|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|x64.ActiveCfg = Debug|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Debug|x64.Build.0 = Debug|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|Any CPU.Build.0 = Release|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|x64.ActiveCfg = Release|Any CPU - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17}.Release|x64.Build.0 = Release|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Debug|x64.ActiveCfg = Debug|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Debug|x64.Build.0 = Debug|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Release|Any CPU.Build.0 = Release|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Release|x64.ActiveCfg = Release|Any CPU + {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2505,37 +2480,35 @@ Global {C0E2763D-13C8-432F-8628-42BFAF57F0FF} = {3198630F-C09B-40AE-B9A1-E79249296E48} {B4E3A1D7-371D-4B0B-A140-94B4F1C23435} = {59BC0E0F-ECEF-4D40-81EC-0EE51CCF9070} {0FA5E9F9-F2D0-46A3-8EA0-809B219B88E8} = {59BC0E0F-ECEF-4D40-81EC-0EE51CCF9070} + {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} = {68491FED-7441-4B58-989D-DF6F198FC91A} + {9BB5CC86-C2E8-4859-9610-50DB263605A3} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} {D10FC534-0091-42B4-809F-82C1E2164ED5} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} {AC84401A-58FD-4786-9E10-BA99D17ABB3E} = {D10FC534-0091-42B4-809F-82C1E2164ED5} - {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} = {68491FED-7441-4B58-989D-DF6F198FC91A} - {9BB5CC86-C2E8-4859-9610-50DB263605A3} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} {8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02} = {8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A} - {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} - {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} - {6C732EBE-22CC-4160-B427-F4558C899024} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} - {B0EFDF9E-81FF-4880-992B-8A65A2008717} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} - {C6E0C9C2-F513-42EE-8C6F-ABCAF82490EB} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} - {EEF78DB2-B9D9-4EC9-806F-6E3502FD0831} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} {03F476EF-022A-4370-B1C3-FEEDE3BB4E7F} = {41769FBF-91A8-48D1-B3BB-CAE4C814E7CD} {A7081ADB-DB21-4678-8510-A5367D470743} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} + {64E37EF0-0C85-4F02-A430-6D3B1DBF13DF} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} {8E74F3D4-9387-4F69-9A17-C793CE2CBAA9} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} {B03C329C-70F4-442A-B420-90DDF7E31847} = {8E74F3D4-9387-4F69-9A17-C793CE2CBAA9} + {43E0F1C0-7308-45C9-83CF-E6291ACE9F0F} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} + {77A9CADA-35D6-419B-87B3-AACC50FFAD0F} = {43E0F1C0-7308-45C9-83CF-E6291ACE9F0F} {4E217EC9-0616-414B-82D9-9107F9826D6E} = {A7081ADB-DB21-4678-8510-A5367D470743} + {A6D4C293-E184-42C0-B9B7-3F856BE57EC0} = {64E37EF0-0C85-4F02-A430-6D3B1DBF13DF} {3FADF704-2581-47AC-A1F7-07091B6328A1} = {A7081ADB-DB21-4678-8510-A5367D470743} {EEB2D542-5A2C-4E18-A0E6-72844C359DAD} = {3FADF704-2581-47AC-A1F7-07091B6328A1} - {64E37EF0-0C85-4F02-A430-6D3B1DBF13DF} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} - {43E0F1C0-7308-45C9-83CF-E6291ACE9F0F} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} - {77A9CADA-35D6-419B-87B3-AACC50FFAD0F} = {43E0F1C0-7308-45C9-83CF-E6291ACE9F0F} + {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA} = {64E37EF0-0C85-4F02-A430-6D3B1DBF13DF} {5E0E61DA-06FF-4F08-9C76-0A8856C90EF5} = {8A9DBB76-6618-4982-87D7-6CBD8375EB15} {356C5F47-025F-4ED6-8E8A-8745E181C455} = {5E0E61DA-06FF-4F08-9C76-0A8856C90EF5} {C2E9EDAE-2558-4899-A486-917AE7A5D24F} = {5E0E61DA-06FF-4F08-9C76-0A8856C90EF5} - {A6D4C293-E184-42C0-B9B7-3F856BE57EC0} = {64E37EF0-0C85-4F02-A430-6D3B1DBF13DF} - {E47D82C7-7A1C-4BEF-ACA8-43971FD6C6BA} = {64E37EF0-0C85-4F02-A430-6D3B1DBF13DF} {8CDAF37E-3DB1-4573-B5AA-376C93A8D299} = {64E37EF0-0C85-4F02-A430-6D3B1DBF13DF} {49B51B95-3DC5-45BD-B91A-3056FF5014B5} = {8CDAF37E-3DB1-4573-B5AA-376C93A8D299} {DD899DC4-A2B7-4C7B-A644-EDB56A61145C} = {8CDAF37E-3DB1-4573-B5AA-376C93A8D299} + {F9E3EBD9-EE96-40F7-BDC7-818B88557D6B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} + {6C732EBE-22CC-4160-B427-F4558C899024} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} + {B0EFDF9E-81FF-4880-992B-8A65A2008717} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} {91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52} = {D2E598D5-5E44-4275-AF03-4BAD07A0E13B} {84F366D3-6E9A-4101-AEC0-287CBA6984A8} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} {F17FFB29-A622-4430-B2EA-E9FF20E68122} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} @@ -2543,8 +2516,7 @@ Global {C99BD51C-A9B8-44FE-BB60-6FCC43E9DA48} = {F17FFB29-A622-4430-B2EA-E9FF20E68122} {921DCAAC-3146-4EDB-891C-D76089E4A451} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} - {95A0DD72-2C64-4C00-A201-94CD7E5BB3F4} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} - {EACF8A3A-13A9-4BAF-81B6-0C651993FC17} = {95A0DD72-2C64-4C00-A201-94CD7E5BB3F4} + {66B1723A-D578-418C-B21C-2C3B5CBD1180} = {5BE84027-D1B4-4264-A7EC-E84658350CA7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs index 1ed056ddd..ca1488ecb 100644 --- a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs +++ b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs @@ -10,90 +10,209 @@ public static class ErrorCode #region Type /// - /// Parameter error + /// Internal service error /// - private const string ARGUMENT = $"{FRAMEWORK_PREFIX}ARG"; + private const string INTERNAL_SERVER = $"{FRAMEWORK_PREFIX}Ser"; /// - /// Internal service error + /// parameter validation error /// - private const string InternalServer = $"{FRAMEWORK_PREFIX}Ser"; + private const string ARGUMENT = $"{FRAMEWORK_PREFIX}ARG"; #endregion - #region Argument + #region Argument Verify + + /// + /// '{PropertyName}' is not a valid email address. + /// + [Description("'{0}' is not a valid email address.")] + public const string EMAIL_VALIDATOR = $"{ARGUMENT}0001"; + + /// + /// '{PropertyName}' must be greater than or equal to '{ComparisonValue}'. + /// + [Description("'{0}' must be greater than or equal to '{1}'.")] + public const string GREATER_THAN_OR_EQUAL_VALIDATOR = $"{ARGUMENT}0002"; + + /// + /// '{PropertyName}' must be greater than '{ComparisonValue}'. + /// + [Description("'{0}' must be greater than '{1}'.")] + public const string GREATER_THAN_VALIDATOR = $"{ARGUMENT}0003"; + + /// + /// '{PropertyName}' must be between {MinLength} and {MaxLength} characters. You entered {TotalLength} characters. + /// + [Description("'{0}' must be between {1} and {2} characters. You entered {3} characters.")] + public const string LENGTH_VALIDATOR = $"{ARGUMENT}0004"; + + /// + /// The length of '{PropertyName}' must be at least {MinLength} characters. You entered {TotalLength} characters. + /// + [Description("The length of '{0}' must be at least {1} characters. You entered {2} characters.")] + public const string MINIMUM_LENGTH_VALIDATOR = $"{ARGUMENT}0005"; + + /// + /// The length of '{PropertyName}' must be {MaxLength} characters or fewer. You entered {TotalLength} characters. + /// + [Description("The length of '{0}' must be {1} characters or fewer. You entered {2} characters.")] + public const string MAXIMUM_LENGTH_VALIDATOR = $"{ARGUMENT}0006"; + + /// + /// '{PropertyName}' must be less than or equal to '{ComparisonValue}'. + /// + [Description("'{0}' must be less than or equal to '{1}'.")] + public const string LESS_THAN_OR_EQUAL_VALIDATOR = $"{ARGUMENT}0007"; + + /// + /// '{PropertyName}' must be less than '{ComparisonValue}'. + /// + [Description("'{0}' must be less than '{1}'.")] + public const string LESS_THAN_VALIDATOR = $"{ARGUMENT}0008"; + + /// + /// '{PropertyName}' must not be empty. + /// + [Description("'{0}' must not be empty.")] + public const string NOT_EMPTY_VALIDATOR = $"{ARGUMENT}0009"; + + /// + /// '{PropertyName}' must not be equal to '{ComparisonValue}'. + /// + [Description("'{0}' must not be equal to '{1}'.")] + public const string NOT_EQUAL_VALIDATOR = $"{ARGUMENT}0010"; + + /// + /// '{PropertyName}' must not be empty. + /// + [Description("'{0}' must not be empty.")] + public const string NOT_NULL_VALIDATOR = $"{ARGUMENT}0011"; + + /// + /// The specified condition was not met for '{0}'. + /// + [Description("The specified condition was not met for '{0}'.")] + public const string PREDICATE_VALIDATOR = $"{ARGUMENT}0012"; + + /// + /// The specified condition was not met for '{0}'. + /// + [Description("The specified condition was not met for '{0}'.")] + public const string ASYNC_PREDICATE_VALIDATOR = $"{ARGUMENT}0013"; + + /// + /// '{PropertyName}' is not in the correct format. + /// + [Description("'{0}' is not in the correct format.")] + public const string REGULAR_EXPRESSION_VALIDATOR = $"{ARGUMENT}0014"; + + /// + /// '{PropertyName}' must be equal to '{ComparisonValue}'. + /// + [Description("'{0}' must be equal to '{1}'.")] + public const string EQUAL_VALIDATOR = $"{ARGUMENT}0015"; + + /// + /// '{PropertyName}' must be {MaxLength} characters in length. You entered {TotalLength} characters. + /// + [Description("'{0}' must be {1} characters in length. You entered {2} characters.")] + public const string EXACT_LENGTH_VALIDATOR = $"{ARGUMENT}0016"; + + /// + /// '{PropertyName}' must be between {From} and {To}. You entered {PropertyValue}. + /// + [Description("'{0}' must be between {1} and {2}. You entered {3}.")] + public const string INCLUSIVE_BETWEEN_VALIDATOR = $"{ARGUMENT}0017"; + + /// + /// '{PropertyName}' must be between {From} and {To} (exclusive). You entered {PropertyValue}. + /// + [Description("'{0}' must be between {1} and {2} (exclusive). You entered {3}.")] + public const string EXCLUSIVE_BETWEEN_VALIDATOR = $"{ARGUMENT}0018"; + + /// + /// '{PropertyName}' cannot be null and empty. + /// + [Description("'{0}' cannot be null and empty.")] + public const string NOT_NULL_AND_EMPTY_VALIDATOR = $"{ARGUMENT}0019"; + + /// + /// '{PropertyName}' must not be more than {ExpectedPrecision} digits in total, with allowance for {ExpectedScale} decimals. {Digits} digits and {ActualScale} decimals were found. + /// + [Description( + "'{0}' must not be more than {1} digits in total, with allowance for {2} decimals. {3} digits and {4} decimals were found.")] + public const string SCALE_PRECISION_VALIDATOR = $"{ARGUMENT}0020"; /// - /// Value Error. (Parameter 'value') + /// '{PropertyName}' must be empty. /// - [Description("Value Error. (Parameter '{0}')")] - public const string ARGUMENT_ERROR = $"{ARGUMENT}0001"; + [Description("'{0}' must be empty.")] public const string EMPTY_VALIDATOR = $"{ARGUMENT}0021"; /// - /// Value cannot be null. (Parameter 'value') + /// '{PropertyName}' must be empty. /// - [Description("Value cannot be null. (Parameter '{0}')")] - public const string ARGUMENT_NULL = $"{ARGUMENT}0002"; + [Description("'{0}' must be empty.")] public const string NULL_VALIDATOR = $"{ARGUMENT}0022"; /// - /// Value cannot be null and empty . (Parameter 'value') + /// '{0}' has a range of values which does not include '{1}'. /// - [Description("Value cannot be null and empty. (Parameter '{0}')")] - public const string ARGUMENT_NULL_OR_EMPTY = $"{ARGUMENT}0003"; + [Description("'{0}' has a range of values which does not include '{1}'.")] + public const string ENUM_VALIDATOR = $"{ARGUMENT}0023"; /// - /// Value cannot be null and WhiteSpace . (Parameter 'value') + /// '{PropertyName}' must be between {MinLength} and {MaxLength} characters. /// - [Description("Value cannot be null and WhiteSpace . (Parameter '{0}')")] - public const string ARGUMENT_NULL_OR_WHITE_SPACE = $"{ARGUMENT}0004"; + [Description("'{0}' must be between {1} and {2} characters.")] + public const string LENGTH_SIMPLE = $"{ARGUMENT}0024"; /// - /// Value must be between {1}-{2} . (Parameter 'value') + /// The length of '{PropertyName}' must be at least {MinLength} characters. /// - [Description("Value must be between {1}-{2} . (Parameter '{0}')")] - public const string ARGUMENT_OUT_OF_RANGE = $"{ARGUMENT}0005"; + [Description("The length of '{0}' must be at least {1} characters.")] + public const string MINIMUM_LENGTH_SIMPLE = $"{ARGUMENT}0025"; /// - /// Value must be greater than {1} . (Parameter 'value') + /// The length of '{0}' must be {1} characters or fewer. /// - [Description("Value must be greater than {1} . (Parameter '{0}')")] - public const string ARGUMENT_GREATER_THAN = $"{ARGUMENT}0006"; + [Description("The length of '{PropertyName}' must be {MaxLength} characters or fewer.")] + public const string MAXIMUM_LENGTH_SIMPLE = $"{ARGUMENT}0026"; /// - /// Value must be greater than or equal {1} . (Parameter 'value') + /// '{0}' must be {1} characters in length. /// - [Description("Value must be greater than or equal {1} . (Parameter '{0}')")] - public const string ARGUMENT_GREATER_THAN_OR_EQUAL = $"{ARGUMENT}0007"; + [Description("'{PropertyName}' must be {MaxLength} characters in length.")] + public const string EXACT_LENGTH_SIMPLE = $"{ARGUMENT}0027"; /// - /// Value must be less than {1} . (Parameter 'value') + /// '{0}' must be between {1} and {2}. /// - [Description("Value must be less than {1} . (Parameter '{0}')")] - public const string ARGUMENT_LESS_THAN = $"{ARGUMENT}0008"; + [Description("'{PropertyName}' must be between {From} and {To}.")] + public const string INCLUSIVE_BETWEEN_SIMPLE = $"{ARGUMENT}0028"; /// - /// Value must be less than or equal {1} . (Parameter 'value') + /// '{PropertyName}' cannot be Null or empty collection. /// - [Description("Value must be less than or equal {1} . (Parameter '{0}')")] - public const string ARGUMENT_LESS_THAN_OR_EQUAL = $"{ARGUMENT}0009"; + [Description("'{0}' cannot be Null or empty collection.")] + public const string NOT_NULL_AND_EMPTY_COLLECTION_VALIDATOR = $"{ARGUMENT}0029"; /// - /// Value cannot contain {1}. (Parameter 'value') + /// '{PropertyName}' cannot be Null or whitespace. /// - [Description("Value cannot contain {1}. (Parameter '{0}')")] - public const string ARGUMENT_NOT_SUPPORTED_SINGLE = $"{ARGUMENT}0010"; + [Description("'{0}' cannot be Null or whitespace.")] + public const string NOT_NULL_AND_WHITESPACE_VALIDATOR = $"{ARGUMENT}0030"; /// - /// Value cannot contain {1} or {2}. (Parameter 'value') + /// '{PropertyName}' cannot contain {Content}. /// - [Description("Value cannot contain {1} or {2}. (Parameter '{0}')")] - public const string ARGUMENT_NOT_SUPPORTED_MULTI = $"{ARGUMENT}0011"; + [Description("'{0}' cannot contain {1}.")] + public const string NOT_CONTAIN_VALIDATOR = $"{ARGUMENT}0031"; /// - /// Value cannot be null or empty collection. (Parameter 'value') + /// '{PropertyName}' must be greater than or equal to '{min}' and less than or equal to '{max}'. /// - [Description("Value cannot be null or empty collection. (Parameter '{0}')")] - public const string ARGUMENT_NULL_OR_EMPTY_COLLECTION = $"{ARGUMENT}0012"; + [Description("'{0}' must be greater than or equal to '{1}' and less than or equal to '{2}'.")] + public const string OUT_OF_RANGE_VALIDATOR = $"{ARGUMENT}0032"; #endregion @@ -103,11 +222,11 @@ public static class ErrorCode /// Internal service error /// [Description("Internal service error")] - public const string INTERNAL_SERVER_ERROR = $"{InternalServer}0001"; + public const string INTERNAL_SERVER_ERROR = $"{INTERNAL_SERVER}0001"; #endregion - private static Dictionary ErrorCodeMessageDictionary = new(); + private static readonly Dictionary _errorCodeMessageDictionary = new(); static ErrorCode() { @@ -117,13 +236,13 @@ static ErrorCode() { var errorMessage = AttributeUtils.GetDescriptionByField(field); - ErrorCodeMessageDictionary.Add(field.GetRawConstantValue()!.ToString(), errorMessage); + _errorCodeMessageDictionary.Add(field.GetRawConstantValue()!.ToString(), errorMessage); } } public static string? GetErrorMessage(string errorCode) { - if (ErrorCodeMessageDictionary.TryGetValue(errorCode, out string? errorMessage)) + if (_errorCodeMessageDictionary.TryGetValue(errorCode, out string? errorMessage)) return errorMessage; return null; diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs index 5b5e299d8..2d28ebc86 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs @@ -13,11 +13,13 @@ public void TestThrowIfNull() try { + MasaValidatorException.ThrowIfNull(""); + MasaArgumentException.ThrowIfNull(str); } catch (MasaArgumentException ex) { - Assert.AreEqual(Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL, ex.ErrorCode); + Assert.AreEqual(Masa.BuildingBlocks.Data.Constants.ErrorCode.NULL_VALIDATOR, ex.ErrorCode); Assert.AreEqual("Value cannot be null. (Parameter '{0}')", ex.ErrorMessage); } } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs index e7fe8da0b..1b2ea778a 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -7,7 +7,7 @@ namespace System; public class MasaArgumentException : MasaException { - public string? ParamName { get; } + protected string? ParamName { get; } public MasaArgumentException(string message) : base(message) @@ -20,19 +20,14 @@ public MasaArgumentException(string message, string paramName) ParamName = paramName; } - public MasaArgumentException(string paramName, params object[] parameters) - : this(paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_ERROR, "", parameters) - { - } - - public MasaArgumentException(string? paramName, string errorCode, string? errorMessage, params object[] parameters) - : this((Exception?)null, errorCode, errorMessage, parameters) + public MasaArgumentException(string? paramName, string errorCode, params object[] parameters) + : this((Exception?)null, errorCode, parameters) { ParamName = paramName; } - public MasaArgumentException(Exception? innerException, string errorCode, string? errorMessage, params object[] parameters) - : base(innerException, errorCode, errorMessage, parameters) + public MasaArgumentException(Exception? innerException, string errorCode, params object[] parameters) + : base(innerException, errorCode, parameters) { } @@ -52,28 +47,28 @@ public static void ThrowIfNullOrEmptyCollection(IEnumerable? arguments, { ThrowIf(arguments is null || !arguments.Any(), paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_EMPTY_COLLECTION); + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_AND_EMPTY_COLLECTION_VALIDATOR); } public static void ThrowIfNull(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) { ThrowIf(argument is null, paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL); + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_VALIDATOR); } public static void ThrowIfNullOrEmpty(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) { ThrowIf(string.IsNullOrEmpty(argument?.ToString()), paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_EMPTY); + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_AND_EMPTY_VALIDATOR); } public static void ThrowIfNullOrWhiteSpace(object? argument, [CallerArgumentExpression("argument")] string? paramName = null) { ThrowIf(string.IsNullOrWhiteSpace(argument?.ToString()), paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NULL_OR_WHITE_SPACE); + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_AND_WHITESPACE_VALIDATOR); } public static void ThrowIfGreaterThan(T argument, @@ -82,7 +77,7 @@ public static void ThrowIfGreaterThan(T argument, { ThrowIf(argument.CompareTo(maxValue) > 0, paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_LESS_THAN_OR_EQUAL, + Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_OR_EQUAL_VALIDATOR, maxValue); } @@ -92,7 +87,7 @@ public static void ThrowIfGreaterThanOrEqual(T argument, { ThrowIf(argument.CompareTo(maxValue) >= 0, paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_LESS_THAN, + Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_VALIDATOR, maxValue); } @@ -102,7 +97,7 @@ public static void ThrowIfLessThan(T argument, { ThrowIf(argument.CompareTo(minValue) < 0, paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_GREATER_THAN_OR_EQUAL, + Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_OR_EQUAL_VALIDATOR, minValue); } @@ -112,7 +107,7 @@ public static void ThrowIfLessThanOrEqual(T argument, { ThrowIf(argument.CompareTo(minValue) <= 0, paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_GREATER_THAN, + Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_VALIDATOR, minValue); } @@ -123,7 +118,7 @@ public static void ThrowIfOutOfRange(T argument, { ThrowIf(argument.CompareTo(minValue) < 0 || argument.CompareTo(maxValue) > 0, paramName, - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_OUT_OF_RANGE, + Masa.BuildingBlocks.Data.Constants.ErrorCode.OUT_OF_RANGE_VALIDATOR, minValue, maxValue); } @@ -137,24 +132,11 @@ public static void ThrowIfContain(string? argument, string parameter, StringComparison stringComparison, [CallerArgumentExpression("argument")] string? paramName = null) - => ThrowIfContain(argument, new[] { parameter }, stringComparison, parameter); - - public static void ThrowIfContain(string? argument, - IEnumerable parameters, - [CallerArgumentExpression("argument")] string? paramName = null) - => ThrowIfContain(argument, parameters, StringComparison.OrdinalIgnoreCase, paramName); - - public static void ThrowIfContain(string? argument, - IEnumerable parameters, - StringComparison stringComparison, - [CallerArgumentExpression("argument")] string? paramName = null) { if (argument != null) - ThrowIf(parameters.Any(parameter => argument.Contains(parameter, stringComparison)), + ThrowIf(argument.Contains(parameter, stringComparison), paramName, - parameters.Count() == 1 ? Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NOT_SUPPORTED_SINGLE : - Masa.BuildingBlocks.Data.Constants.ErrorCode.ARGUMENT_NOT_SUPPORTED_MULTI, - parameters + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_CONTAIN_VALIDATOR ); } @@ -170,7 +152,10 @@ public static void ThrowIf(bool condition, string? paramName, string errorCode, [DoesNotReturn] private static void Throw(string? paramName, string errorCode, string? errorMessage, params object[] parameters) => - throw new MasaArgumentException(paramName, errorCode, errorMessage, parameters); + throw new MasaArgumentException(paramName, errorCode, parameters) + { + ErrorMessage = errorMessage + }; protected override object[] GetParameters() { diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index db8ce73bf..d125c3b86 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -79,16 +79,15 @@ public MasaException(string message) { } - public MasaException(string errorCode, string? errorMessage, params object[] parameters) - : this(null, errorCode, errorMessage, parameters) + public MasaException(string errorCode, params object[] parameters) + : this(null, errorCode, parameters) { } - public MasaException(Exception? innerException, string errorCode, string? errorMessage, params object[] parameters) + public MasaException(Exception? innerException, string errorCode, params object[] parameters) : base(null, innerException) { ErrorCode = errorCode; - ErrorMessage = errorMessage; Parameters = parameters; } @@ -102,15 +101,15 @@ public MasaException(SerializationInfo serializationInfo, StreamingContext conte { } - public string GetLocalizationMessage() + public string GetLocalizedMessage() { if (string.IsNullOrWhiteSpace(ErrorCode)) return Message; - return GetLocalizationMessageExecuting(); + return GetLocalizedMessageExecuting(); } - protected virtual string GetLocalizationMessageExecuting() + protected virtual string GetLocalizedMessageExecuting() { if (!SupportI18N) { diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs index 2010c5e75..273eb0d29 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaHttpStatusCode.cs @@ -7,5 +7,9 @@ namespace System; public enum MasaHttpStatusCode { + /// + /// form validation exception + /// + ValidatorException = 298, UserFriendlyException = 299 } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs new file mode 100644 index 000000000..f1c4e9ee4 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs @@ -0,0 +1,211 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class MasaValidatorException : MasaArgumentException +{ + public MasaValidatorException(string message) + : base(message) + { + } + + public MasaValidatorException(string? paramName, string errorCode, params object[] parameters) + : base(paramName, errorCode, parameters) + { + + } + + public MasaValidatorException(Exception? innerException, string errorCode, params object[] parameters) + : base(innerException, errorCode, parameters) + { + } + + public MasaValidatorException(params ValidationModel[] validationModels) + : base(FormatMessage(validationModels)) + { + + } + + public MasaValidatorException(string message, Exception? innerException) + : base(message, innerException) + { + } + + public MasaValidatorException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) + { + } + + private static string FormatMessage(params ValidationModel[] models) + => FormatMessage(models.ToList()); + + private static string FormatMessage(IEnumerable models) + { + var stringBuilder = new Text.StringBuilder(); + stringBuilder.AppendLine("Validation failed: "); + foreach (var model in models) + { + stringBuilder.AppendLine($"-- {model.Name}: {model.Message} Severity: {model.Level.ToString()}"); + } + return stringBuilder.ToString(); + } + + public new static void ThrowIfNullOrEmptyCollection(IEnumerable? arguments, + [CallerArgumentExpression("arguments")] + string? paramName = null) + { + ThrowIf(arguments is null || !arguments.Any(), + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_AND_EMPTY_COLLECTION_VALIDATOR); + } + + public new static void ThrowIfNull( + object? argument, + [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(argument is null, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_VALIDATOR); + } + + public new static void ThrowIfNullOrEmpty( + object? argument, + [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(string.IsNullOrEmpty(argument?.ToString()), + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_AND_EMPTY_VALIDATOR); + } + + public new static void ThrowIfNullOrWhiteSpace( + object? argument, + [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIf(string.IsNullOrWhiteSpace(argument?.ToString()), + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_NULL_AND_WHITESPACE_VALIDATOR); + } + + public new static void ThrowIfGreaterThan(T argument, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(maxValue) > 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_OR_EQUAL_VALIDATOR, + maxValue); + } + + public new static void ThrowIfGreaterThanOrEqual(T argument, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(maxValue) >= 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_VALIDATOR, + maxValue); + } + + public new static void ThrowIfLessThan(T argument, + T minValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) < 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_OR_EQUAL_VALIDATOR, + minValue); + } + + public new static void ThrowIfLessThanOrEqual(T argument, + T minValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) <= 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_VALIDATOR, + minValue); + } + + public new static void ThrowIfOutOfRange(T argument, + T minValue, + T maxValue, + [CallerArgumentExpression("argument")] string? paramName = null) where T : IComparable + { + ThrowIf(argument.CompareTo(minValue) < 0 || argument.CompareTo(maxValue) > 0, + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.OUT_OF_RANGE_VALIDATOR, + minValue, + maxValue); + } + + public new static void ThrowIfContain(string? argument, + string parameter, + [CallerArgumentExpression("argument")] string? paramName = null) + => ThrowIfContain(argument, parameter, StringComparison.OrdinalIgnoreCase, paramName); + + public new static void ThrowIfContain(string? argument, + string parameter, + StringComparison stringComparison, + [CallerArgumentExpression("argument")] string? paramName = null) + { + if (argument != null) + ThrowIf(argument.Contains(parameter, stringComparison), + paramName, + Masa.BuildingBlocks.Data.Constants.ErrorCode.NOT_CONTAIN_VALIDATOR + ); + } + + public new static void ThrowIf( + bool condition, + string? paramName, + string errorCode, + params object[] parameters) + { + if (condition) Throw(paramName, errorCode, Masa.BuildingBlocks.Data.Constants.ErrorCode.GetErrorMessage(errorCode), parameters); + } + + public new static void ThrowIf( + bool condition, + string? paramName, + string errorCode, + string? errorMessage, + params object[] parameters) + { + if (condition) Throw(paramName, errorCode, errorMessage, parameters); + } + + [DoesNotReturn] + private static void Throw( + string? paramName, + string errorCode, + string? errorMessage, + params object[] parameters) + => throw new MasaValidatorException(paramName, errorCode, parameters) + { + ErrorMessage = errorMessage + }; + + protected override string GetLocalizedMessageExecuting() + { + string message; + if (!SupportI18N) + { + message = string.IsNullOrWhiteSpace(ErrorMessage) ? Message : string.Format(ErrorMessage, GetParameters()); + } + + else if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) + { + //The current framework frame exception + message = FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; + } + else + { + message = I18N!.T(ErrorCode, false, GetParameters()) ?? Message; + } + + return FormatMessage(new ValidationModel(ParamName!, message)); + } +} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationLevel.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationLevel.cs new file mode 100644 index 000000000..aceee4b08 --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationLevel.cs @@ -0,0 +1,15 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +/// +/// Form validation error level +/// +public enum ValidationLevel +{ + Warning = 1, + Error = 2 +} diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationModel.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationModel.cs new file mode 100644 index 000000000..7beb06e4f --- /dev/null +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/ValidationModel.cs @@ -0,0 +1,27 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace System; + +public class ValidationModel +{ + public string Name { get; set; } + + public string Message { get; set; } + + public ValidationLevel Level { get; set; } + + public ValidationModel(ValidationLevel level = ValidationLevel.Error) + { + Level = level; + } + + public ValidationModel(string name, string message, ValidationLevel level = ValidationLevel.Error) + : this(level) + { + Name = name; + Message = message; + } +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs new file mode 100644 index 000000000..5413386d4 --- /dev/null +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs @@ -0,0 +1,80 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Globalization.I18N; + +public static class I18N +{ + private static readonly IServiceProvider _serviceProvider = MasaApp.RootServiceProvider; + private static readonly II18N _i18N = InitI18N(); + + static II18N InitI18N() => _serviceProvider.GetRequiredService(); + + /// + /// Gets the string resource with the given name. + /// + /// The name of the string resource. + /// + public static string T(string name) => _i18N.T(name); + + /// + /// Gets the string resource with the given name. + /// + /// The name of the string resource. + /// Return Key when key does not exist, default: true + /// + public static string? T(string name, bool returnKey) => _i18N.T(name, returnKey); + + /// + /// Gets the string resource with the given name and formatted with the supplied arguments. + /// + /// The name of the string resource. + /// The values to format the string with. + public static string T(string name, params object[] arguments) => _i18N.T(name, arguments); + + /// + /// Gets the string resource with the given name and formatted with the supplied arguments. + /// + /// The name of the string resource. + /// Return Key when key does not exist, default: true + /// The values to format the string with. + public static string? T(string name, bool returnKey, params object[] arguments) => _i18N.T(name, returnKey, arguments); + + public static CultureInfo GetCultureInfo() => _i18N.GetCultureInfo(); + + /// + /// Set the CultureName + /// Data used to define "regional options", standards, formats, etc + /// + /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. + /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). + public static void SetCulture(string cultureName, bool useUserOverride = true) => _i18N.SetCulture(cultureName, useUserOverride); + + /// + /// Set the CultureName + /// Data used to define "regional options", standards, formats, etc + /// + /// + public static void SetCulture(CultureInfo culture) => _i18N.SetCulture(culture); + + /// + /// get interface language + /// + /// + public static CultureInfo GetUiCultureInfo() => _i18N.GetUiCultureInfo(); + + /// + /// Set the CultureName for the current request + /// Used to set the interface language + /// + /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. + /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). + public static void SetUiCulture(string cultureName, bool useUserOverride = true) => _i18N.SetUiCulture(cultureName, useUserOverride); + + /// + /// Set the CultureName for the current request + /// Used to set the interface language + /// + /// + public static void SetUiCulture(CultureInfo culture) => _i18N.SetUiCulture(culture); +} diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs index b43ff527e..14eb727ee 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs @@ -5,6 +5,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; +[InheritResource(typeof(MasaFrameworkResource))] public class DefaultResource { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs index 161873e71..7a55cc238 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs @@ -8,7 +8,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; /// /// Framework Multilingual Resources /// -[InheritResource(typeof(MasaExceptionResource))] +[InheritResource(typeof(MasaParameterValidationResource), typeof(MasaLanguageResource))] public class MasaFrameworkResource { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs index 67006b40b..c8da63476 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs @@ -7,5 +7,5 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public class MasaLanguageResource { - + } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaExceptionResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs similarity index 87% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaExceptionResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs index 1acf9f0e2..fba86e0a7 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaExceptionResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs @@ -8,7 +8,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; /// /// Framework Multilingual Resources /// -public class MasaExceptionResource +public class MasaParameterValidationResource { } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index 1ec7d0dd4..4e28edc68 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -1,6 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Data; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Options; global using System.Globalization; diff --git a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Masa.Contrib.Dispatcher.Events.FluentValidation.csproj b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Masa.Contrib.Dispatcher.Events.FluentValidation.csproj new file mode 100644 index 000000000..24fd9c642 --- /dev/null +++ b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Masa.Contrib.Dispatcher.Events.FluentValidation.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs new file mode 100644 index 000000000..cdf1cfc3c --- /dev/null +++ b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs @@ -0,0 +1,45 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +// ReSharper disable once CheckNamespace + +namespace Masa.Contrib.Dispatcher.Events; + +public class ValidatorMiddleware : Middleware + where TEvent : IEvent +{ + private readonly ILogger> _logger; + private readonly IEnumerable> _validators; + + public ValidatorMiddleware(IEnumerable> validators, ILogger> logger) + { + _validators = validators; + _logger = logger; + } + + public override async Task HandleAsync(TEvent @event, EventHandlerDelegate next) + { + var typeName = @event.GetType().FullName; + + _logger.LogDebug("----- Validating command {CommandType}", typeName); + + var failures = _validators + .Select(v => v.Validate(@event)) + .SelectMany(result => result.Errors) + .Where(error => error != null) + .ToList(); + + if (failures.Any()) + { + _logger.LogError("Validation errors - {CommandType} - Event: {@Command} - Errors: {@ValidationErrors}", + typeName, + @event, + failures); + + var validationException = new ValidationException("Validation exception", failures); + throw new MasaValidatorException(validationException.Message); + } + + await next(); + } +} diff --git a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/_Imports.cs b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/_Imports.cs new file mode 100644 index 000000000..7dfdb7c26 --- /dev/null +++ b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/_Imports.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using FluentValidation; +global using Masa.BuildingBlocks.Dispatcher.Events; +global using Microsoft.Extensions.Logging; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index ccd73dec4..b8a9061de 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -16,13 +16,12 @@ public static class ApplicationBuilderExtensions /// public static IApplicationBuilder UseMasaExceptionHandler( this IApplicationBuilder app, - Action? exceptionHandlingOptions = null, - bool useI18N = true) + Action? exceptionHandlingOptions = null) { var option = new MasaExceptionHandlerOptions(); exceptionHandlingOptions?.Invoke(option); - if (useI18N) app.UseI18N(); + app.UseI18N(); app.UseMiddleware(Options.Create(option)); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index 2effeeb4f..3011e29a8 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -62,7 +62,7 @@ await httpContext.Response.WriteTextAsync( if (masaExceptionContext.Exception is MasaException masaException) { - await httpContext.Response.WriteTextAsync(httpStatusCode, masaException.GetLocalizationMessage()); + await httpContext.Response.WriteTextAsync(httpStatusCode, masaException.GetLocalizedMessage()); } else if (_options.CatchAllException) { diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs index 7b511509a..38b9288fe 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs @@ -63,7 +63,7 @@ public void OnException(ExceptionContext context) if (masaExceptionContext.Exception is MasaException masaException) { context.ExceptionHandled = true; - context.Result = new DefaultExceptionResult(masaException.GetLocalizationMessage(), + context.Result = new DefaultExceptionResult(masaException.GetLocalizedMessage(), httpStatusCode, masaExceptionContext.ContentType); return; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs index 2a3962787..b8856b1a6 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs @@ -10,6 +10,9 @@ public static int GetHttpStatusCode(this Exception exception) if (exception is UserFriendlyException) return (int)MasaHttpStatusCode.UserFriendlyException; + if (exception is MasaValidatorException) + return (int)MasaHttpStatusCode.ValidatorException; + return (int)HttpStatusCode.InternalServerError; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs index a8efdaa78..7f2f3df55 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs @@ -11,7 +11,7 @@ public static class Constant internal static readonly string DefaultFrameworkResourcePath; - internal static readonly string DefaultFrameworkExceptionResourcePath; + internal static readonly string DefaultFrameworkParameterValidationResourcePath; internal static readonly string DefaultFrameworkLanguageResourcePath; @@ -19,7 +19,7 @@ static Constant() { DefaultResourcePath = Path.Combine("Resources", "I18n"); DefaultFrameworkResourcePath = Path.Combine(DefaultResourcePath, "Framework"); - DefaultFrameworkExceptionResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Exceptions"); + DefaultFrameworkParameterValidationResourcePath = Path.Combine(DefaultFrameworkResourcePath, "ParameterValidations"); DefaultFrameworkLanguageResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Languages"); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs index bc1c4f889..606ca13de 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs @@ -47,6 +47,6 @@ public List> GetResources(string resourcesDirec private string FormatResourcesDirectory(string resourcesDirectory) { - return resourcesDirectory.Replace("\\", "."); + return resourcesDirectory.Replace(Path.DirectorySeparatorChar.ToString(), "."); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index 3945aa338..edd13605b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -88,14 +88,14 @@ private static IServiceCollection AddI18NByFramework(this IServiceCollection ser options.Resources.TryAdd(resource => { resource.AddJsonByEmbeddedResource(new[] { assembly }, - languageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, + ContribI18NConstant.DefaultFrameworkResourcePath, languageSettings.SupportedCultures); }); - options.Resources.TryAdd(resource => + options.Resources.TryAdd(resource => { resource.AddJsonByEmbeddedResource(new[] { assembly }, - ContribI18NConstant.DefaultFrameworkExceptionResourcePath, + ContribI18NConstant.DefaultFrameworkParameterValidationResourcePath, languageSettings.SupportedCultures); }); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index ef039112e..587bc9dc4 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -19,6 +19,7 @@ + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/en-US.json deleted file mode 100644 index b99af84d6..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/en-US.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "MFARG0001": "Value Error. (Parameter '{0}')", - "MFARG0002": "Value cannot be null. (Parameter '{0}')", - "MFARG0003": "Value cannot be null and empty. (Parameter '{0}')", - "MFARG0004": "Value cannot be null and WhiteSpace . (Parameter '{0}')", - "MFARG0005": "Value must be between {1}-{2} . (Parameter '{0}')", - "MFARG0006": "Value must be greater than {1} . (Parameter '{0}')", - "MFARG0007": "Value must be greater than or equal {1} . (Parameter '{0}')", - "MFARG0008": "Value must be less than {1} . (Parameter '{0}')", - "MFARG0009": "Value must be less than or equal {1} . (Parameter '{0}')", - "MFARG0010": "Value cannot contain {1}. (Parameter '{0}')", - "MFARG0011": "Value cannot contain {1} or {2}. (Parameter '{0}')", - "MFARG0012": "Value cannot be null or empty collection. (Parameter '{0}')", - "MFSer0001": "Internal service error" -} \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/zh-CN.json deleted file mode 100644 index 52e227eda..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Exceptions/zh-CN.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "MFARG0001": "参数错误. (Parameter '{0}')", - "MFARG0002": "值不能为null. (Parameter '{0}')", - "MFARG0003": "值不能为null和Empty. (Parameter '{0}')", - "MFARG0004": "值不能为null和WhiteSpace. (Parameter '{0}')", - "MFARG0005": "值必须介于{1}-{2} . (Parameter '{0}')", - "MFARG0006": "值必须大于{1}. (Parameter '{0}')", - "MFARG0007": "值必须大于或等于{1}. (Parameter '{0}')", - "MFARG0008": "值必须小于{1}. (Parameter '{0}')", - "MFARG0009": "值必须小于或等于{1}. (Parameter '{0}')", - "MFARG0010": "值不能包含{1}. (Parameter '{0}')", - "MFARG0011": "值不能包含{1}或{2}. (Parameter '{0}')", - "MFARG0012": "值不能为null或空集合. (Parameter '{0}')", - "MFSer0001": "内部服务出错" -} \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json new file mode 100644 index 000000000..d95b09692 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json @@ -0,0 +1,34 @@ +{ + "MFARG0001" : "'{0}' is not a valid email address.", + "MFARG0002" : "'{0}' must be greater than or equal to '{1}'.", + "MFARG0003" : "'{0}' must be greater than '{1}'.", + "MFARG0004" : "'{0}' must be between {1} and {2} characters. You entered {3} characters.", + "MFARG0005" : "The length of '{0}' must be at least {1} characters. You entered {2} characters.", + "MFARG0006" : "The length of '{0}' must be {1} characters or fewer. You entered {2} characters.", + "MFARG0007" : "'{0}' must be less than or equal to '{1}'.", + "MFARG0008" : "'{0}' must be less than '{1}'.", + "MFARG0009" : "'{0}' must not be empty.", + "MFARG0010" : "'{0}' must not be equal to '{1}'.", + "MFARG0011" : "'{0}' must not be empty.", + "MFARG0012" : "The specified condition was not met for '{0}'.", + "MFARG0013" : "The specified condition was not met for '{0}'.", + "MFARG0014" : "'{0}' is not in the correct format.", + "MFARG0015" : "'{0}' must be equal to '{1}'.", + "MFARG0016" : "'{0}' must be {1} characters in length. You entered {2} characters.", + "MFARG0017" : "'{0}' must be between {1} and {2}. You entered {3}.", + "MFARG0018" : "'{0}' must be between {1} and {2} (exclusive). You entered {3}.", + "MFARG0019" : "'{0}' cannot be null and empty.", + "MFARG0020" : "'{0}' must not be more than {1} digits in total, with allowance for {2} decimals. {3} digits and {4} decimals were found.", + "MFARG0021" : "'{0}' must be empty.", + "MFARG0022" : "'{0}' must be empty.", + "MFARG0023" : "'{0}' has a range of values which does not include '{1}'.", + "MFARG0024" : "'{0}' must be between {1} and {2} characters.", + "MFARG0025" : "The length of '{0}' must be at least {1} characters.", + "MFARG0026" : "The length of '{0}' must be {1} characters or fewer.", + "MFARG0027" : "'{0}' must be {1} characters in length.", + "MFARG0028" : "'{0}' must be between {1} and {2}.", + "MFARG0029" : "'{0}' cannot be Null or empty collection.", + "MFARG0030" : "'{0}' cannot be Null or whitespace.", + "MFARG0031" : "'{0}' cannot contain {1}.", + "MFARG0032" : "'{0}' must be greater than or equal to '{1}' and less than or equal to '{2}'." +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json new file mode 100644 index 000000000..2e64a44d7 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json @@ -0,0 +1,34 @@ +{ + "MFARG0001" : "'{0}' 不是有效的电子邮件地址。", + "MFARG0002" : "'{0}' 必须大于或等于 '{1}'。", + "MFARG0003" : "'{0}' 必须大于 '{1}'。", + "MFARG0004" : "'{0}' 的长度必须在 {1} 到 {2} 字符,您输入了 {3} 字符。", + "MFARG0005" : "'{0}' 必须大于或等于{1}个字符。您输入了{2}个字符。", + "MFARG0006" : "'{0}' 必须小于或等于{1}个字符。您输入了{2}个字符。", + "MFARG0007" : "'{0}' 必须小于或等于 '{1}'。", + "MFARG0008" : "'{0}' 必须小于 '{1}'。", + "MFARG0009" : "'{0}' 不能为空。", + "MFARG0010" : "'{0}' 不能和 '{1}' 相等。", + "MFARG0011" : "'{0}' 不能为Null。", + "MFARG0012" : "'{0}' 不符合指定的条件。", + "MFARG0013" : "'{0}' 不符合指定的条件。", + "MFARG0014" : "'{0}' 的格式不正确。", + "MFARG0015" : "'{0}' 应该和 '{1}' 相等。", + "MFARG0016" : "'{0}' 必须是 {1} 个字符,您输入了 {2} 字符。", + "MFARG0017" : "'{0}' 必须在 {1} (包含)和 {2} (包含)之间, 您输入了 {3}。", + "MFARG0018" : "'{0}' 必须在 {1} (不包含)和 {2} (不包含)之间, 您输入了 {3}。", + "MFARG0019" : "'{0}' 不能为Null和空字符。", + "MFARG0020" : "'{0}' 总位数不能超过 {1} 位,其中小数部分 {2} 位。您共计输入了 {3} 位数字,其中小数部分{4} 位。", + "MFARG0021" : "'{0}' 必须为空。", + "MFARG0022" : "'{0}' 必须为Null。", + "MFARG0023" : "'{0}' 的值范围不包含 '{1}'。", + "MFARG0024" : "'{0}' 的长度必须在 {1} 到 {2} 字符。", + "MFARG0025" : "'{0}' 必须大于或等于{1}个字符。", + "MFARG0026" : "'{0}' 必须小于或等于{1}个字符。", + "MFARG0027" : "'{0}' 必须是 {1} 个字符。", + "MFARG0028" : "'{0}' 必须在 {1} (包含)和 {2} (包含)之间。", + "MFARG0029" : "'{0}' 不能为Null或空集合。", + "MFARG0030" : "'{0}' 不能为Null或空白字符。", + "MFARG0031" : "'{0}' 不能包含{1}。", + "MFARG0032" : "'{0}' 必须大于等于 '{1}' 且 小于等于 '{2}'。" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json new file mode 100644 index 000000000..2a3ecdada --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json @@ -0,0 +1,3 @@ +{ + "MFSer0001": "Internal service error" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json new file mode 100644 index 000000000..a52be869b --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json @@ -0,0 +1,3 @@ +{ + "MFSer0001": "内部服务出错" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj deleted file mode 100644 index 980919745..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - net6.0 - enable - false - enable - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - Always - - - Always - - - Always - - - - diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json deleted file mode 100644 index d7e013916..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/en-US.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Name": "Jim", - "User": { - "Name": "Jim2" - } -} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json deleted file mode 100644 index c334e66de..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/supportedCultures.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "Culture": "zh-CN", - "Display": "中文简体" - }, - { - "Culture": "en-US", - "Display": "English (United States)" - } -] \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json deleted file mode 100644 index c76dfe1f6..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/Resources/i18n/zh-CN.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Name": "吉姆", - "User": { - "Name": "Jim2" - } -} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs deleted file mode 100644 index d1247c95d..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/ServicesCollectionsTest.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18N.Blazor.Tests; - -[TestClass] -public class ServicesCollectionsTest -{ - [TestMethod] - public void TestAddI18NForBlazor() - { - var services = new ServiceCollection(); - services.AddI18NForBlazorServer(); - var descriptor = ServiceDescriptor.Transient(typeof(II18N<>), typeof(I18NOfT<>)); - Assert.IsTrue(services.Any(d - => d.ServiceType == descriptor.ServiceType && d.Lifetime == descriptor.Lifetime && - d.ImplementationType == descriptor.ImplementationType)); - } -} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs deleted file mode 100644 index 095d8021c..000000000 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Blazor.Tests/_Imports.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -global using Masa.BuildingBlocks.Globalization.I18N; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs index bca6b7120..d54cae82f 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs @@ -17,82 +17,35 @@ public DefaultResponseMessage(IOptions options, ILogger ProcessResponseAsync(HttpResponseMessage response, CancellationToken cancellationToken = default) { - var responseType = typeof(TResponse); - if (response.IsSuccessStatusCode) + await ProcessResponseAsync(response, cancellationToken); + + switch (response.StatusCode) { - switch (response.StatusCode) - { - case HttpStatusCode.Accepted: - case HttpStatusCode.NoContent: - return default; - case (HttpStatusCode)MasaHttpStatusCode.UserFriendlyException: - throw new UserFriendlyException(await response.Content.ReadAsStringAsync(cancellationToken)); - default: - if (responseType == typeof(Guid) || responseType == typeof(Guid?)) - { - var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); - if (IsNullOrEmpty(content)) - return default; - - return (TResponse?)(object)Guid.Parse(content); - } - if (responseType == typeof(DateTime) || responseType == typeof(DateTime?)) - { - var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); - if (IsNullOrEmpty(content)) - return default; - - return (TResponse?)(object)DateTime.Parse(content); - } - - var actualType = Nullable.GetUnderlyingType(responseType); - - if (responseType.GetInterfaces().Any(type => type == typeof(IConvertible)) || - (actualType != null && actualType.GetInterfaces().Any(type => type == typeof(IConvertible)))) - { - var content = await response.Content.ReadAsStringAsync(cancellationToken); - if (IsNullOrEmpty(content)) - return default; - - if (actualType != null) - return (TResponse?)Convert.ChangeType(content, actualType); - - return (TResponse?)Convert.ChangeType(content, responseType); - } - - try - { - return await response.Content.ReadFromJsonAsync( - _options.JsonSerializerOptions?? MasaApp.GetJsonSerializerOptions() - , cancellationToken); - } - catch (Exception exception) - { - _logger?.LogWarning(exception, exception.Message); - ExceptionDispatchInfo.Capture(exception).Throw(); - return default; //This will never be executed, the previous line has already thrown an exception - } - } + case HttpStatusCode.Accepted: + case HttpStatusCode.NoContent: + return default; + default: + return await FormatResponseAsync(response, cancellationToken); } - - await ProcessResponseExceptionAsync(response, cancellationToken); - return default; //never executed } public async Task ProcessResponseAsync(HttpResponseMessage response, CancellationToken cancellationToken = default) { - if (response.IsSuccessStatusCode) + if (!response.IsSuccessStatusCode) { - switch (response.StatusCode) - { - case (HttpStatusCode)MasaHttpStatusCode.UserFriendlyException: - throw new UserFriendlyException(await response.Content.ReadAsStringAsync(cancellationToken)); - default: - return; - } + await ProcessResponseExceptionAsync(response, cancellationToken); + return; } - await ProcessResponseExceptionAsync(response, cancellationToken); + switch (response.StatusCode) + { + case (HttpStatusCode)MasaHttpStatusCode.UserFriendlyException: + throw new UserFriendlyException(await response.Content.ReadAsStringAsync(cancellationToken)); + case (HttpStatusCode)MasaHttpStatusCode.ValidatorException: + throw new MasaValidatorException(await response.Content.ReadAsStringAsync(cancellationToken)); + default: + return; + } } public async Task ProcessResponseExceptionAsync(HttpResponseMessage response, CancellationToken cancellationToken = default) @@ -103,5 +56,55 @@ public async Task ProcessResponseExceptionAsync(HttpResponseMessage response, Ca throw new MasaException($"ReasonPhrase: {response.ReasonPhrase ?? string.Empty}, StatusCode: {response.StatusCode}"); } + private async Task FormatResponseAsync(HttpResponseMessage response, + CancellationToken cancellationToken = default) + { + var responseType = typeof(TResponse); + if (responseType == typeof(Guid) || responseType == typeof(Guid?)) + { + var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); + if (IsNullOrEmpty(content)) + return default; + + return (TResponse?)(object)Guid.Parse(content); + } + if (responseType == typeof(DateTime) || responseType == typeof(DateTime?)) + { + var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); + if (IsNullOrEmpty(content)) + return default; + + return (TResponse?)(object)DateTime.Parse(content); + } + + var actualType = Nullable.GetUnderlyingType(responseType); + + if (responseType.GetInterfaces().Any(type => type == typeof(IConvertible)) || + (actualType != null && actualType.GetInterfaces().Any(type => type == typeof(IConvertible)))) + { + var content = await response.Content.ReadAsStringAsync(cancellationToken); + if (IsNullOrEmpty(content)) + return default; + + if (actualType != null) + return (TResponse?)Convert.ChangeType(content, actualType); + + return (TResponse?)Convert.ChangeType(content, responseType); + } + + try + { + return await response.Content.ReadFromJsonAsync( + _options.JsonSerializerOptions ?? MasaApp.GetJsonSerializerOptions() + , cancellationToken); + } + catch (Exception exception) + { + _logger?.LogWarning(exception, exception.Message); + ExceptionDispatchInfo.Capture(exception).Throw(); + return default; //This will never be executed, the previous line has already thrown an exception + } + } + private static bool IsNullOrEmpty(string value) => string.IsNullOrEmpty(value) || value == "null"; } From 52aaa75141df478a99a1bad02b4dc6837bdbeea1 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 9 Nov 2022 20:33:59 +0800 Subject: [PATCH 27/38] feat(I18n): Support I18N --- .../Constants/ErrorCode.cs | 2 +- .../CultureModel.cs | 4 +- .../DefaultLanguageProvider.cs | 16 ++- .../I18N.cs | 5 + .../I18NResource.cs | 16 ++- .../Middleware/ValidatorMiddleware.cs | 8 +- .../ApplicationBuilderExtensions.cs | 1 + .../Extensions/MvcBuilderExtensions.cs | 1 + .../Handlers/ExceptionHandlerMiddleware.cs | 1 + .../Handlers/MvcGlobalExceptionFilter.cs | 1 + .../Internal/Constant.cs | 2 - .../Internal/ExceptionExtensions.cs | 1 + .../Internal/HttpResponseExtensions.cs | 1 + .../Internal/LoggerExtensions.cs | 1 + .../Internal/ServiceProviderExtensions.cs | 1 + .../MasaExceptionContext.cs | 1 + .../Options/MasaExceptionHandlerOptions.cs | 1 + .../MasaExceptionLogRelationOptions.cs | 3 +- .../Results/DefaultExceptionResult.cs | 1 + .../InternalServerErrorObjectResult.cs | 1 + .../Results/UserFriendlyExceptionResult.cs | 1 + .../Masa.Contrib.Exceptions/_Imports.cs | 1 + .../ApplicationBuilderExtensions.cs | 1 + .../README.md | 98 +++++++++++++++++++ .../README.zh-CN.md | 98 +++++++++++++++++++ .../_Imports.cs | 1 + .../DccI18NResourceContributor.cs | 4 +- .../DccResource.cs | 9 ++ .../Extensions/I18NOptionsExtensions.cs | 14 ++- .../Extensions/I18NResourceExtensions.cs | 6 +- .../_Imports.cs | 1 + .../Extensions/I18NResourceExtensions.cs | 17 ---- .../Extensions/ServiceCollectionExtensions.cs | 27 ++--- .../Masa.Contrib.Globalization.I18N/README.md | 40 +++++--- .../README.zh-CN.md | 40 +++++--- .../Framework/ParameterValidations/zh-CN.json | 2 +- .../_Imports.cs | 2 +- .../I18NTest.cs | 49 ++++++++++ ...ontrib.Globalization.I18N.Dcc.Tests.csproj | 13 +++ .../Resources/I18n/en-US.json | 3 + .../Resources/I18n/supportedCultures.json | 10 ++ .../Resources/I18n/zh-CN.json | 3 + .../_Imports.cs | 7 ++ .../I18NTest.cs | 6 +- ...sa.Contrib.Globalization.I18N.Tests.csproj | 8 +- 45 files changed, 428 insertions(+), 101 deletions(-) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json create mode 100644 src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json diff --git a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs index ca1488ecb..135f9df5a 100644 --- a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs +++ b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs @@ -236,7 +236,7 @@ static ErrorCode() { var errorMessage = AttributeUtils.GetDescriptionByField(field); - _errorCodeMessageDictionary.Add(field.GetRawConstantValue()!.ToString(), errorMessage); + _errorCodeMessageDictionary.Add(field.GetRawConstantValue()!.ToString()!, errorMessage); } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs index ec674d744..6c6bba727 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs @@ -7,11 +7,11 @@ public class CultureModel { public string Culture { get; set; } - public string DisplayName { get; set; } + public string? DisplayName { get; set; } public string Icon { get; set; } - public CultureModel(string culture, string displayName, string? icon = null) + public CultureModel(string culture, string? displayName = null, string? icon = null) { Culture = culture; DisplayName = displayName; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs index 45e9a574e..f3991ff8a 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs @@ -8,6 +8,12 @@ public class DefaultLanguageProvider : ILanguageProvider private readonly II18N _i18N; private readonly IOptions _options; + private static Dictionary _languages = new() + { + { "en-US", "English (United States)" }, + { "zh-CN", "中文 (简体)" } + }; + public DefaultLanguageProvider(II18N i18N, IOptions options) { _i18N = i18N; @@ -24,7 +30,7 @@ public IReadOnlyList GetLanguages() nameof(LanguageInfo.UIDisplayName) : $"{culture.Culture}\\.{nameof(LanguageInfo.UIDisplayName)}"; var uiDisplayName = _i18N.T(key); - var languageInfo = new LanguageInfo(culture.Culture, culture.DisplayName, culture.Icon) + var languageInfo = new LanguageInfo(culture.Culture, culture.DisplayName ?? GetDisplayName(cultureName), culture.Icon) { UIDisplayName = uiDisplayName }; @@ -33,4 +39,12 @@ public IReadOnlyList GetLanguages() }); return list; } + + private static string GetDisplayName(string cultureName) + { + if (_languages.TryGetValue(cultureName, out string? displayName)) + return displayName; + + return string.Empty; + } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs index 5413386d4..254effc2a 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs @@ -7,9 +7,12 @@ public static class I18N { private static readonly IServiceProvider _serviceProvider = MasaApp.RootServiceProvider; private static readonly II18N _i18N = InitI18N(); + private static readonly ILanguageProvider _languageProvider = InitLanguage(); static II18N InitI18N() => _serviceProvider.GetRequiredService(); + static ILanguageProvider InitLanguage() => _serviceProvider.GetRequiredService(); + /// /// Gets the string resource with the given name. /// @@ -77,4 +80,6 @@ public static class I18N /// /// public static void SetUiCulture(CultureInfo culture) => _i18N.SetUiCulture(culture); + + public static IReadOnlyList GetLanguages() => _languageProvider.GetLanguages(); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs index 0d0976408..5efdc7572 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs @@ -9,7 +9,7 @@ public class I18NResource public Type ResourceType { get; } - public IEnumerable BaseResourceTypes { get; } + public List BaseResourceTypes { get; private set; } public IEnumerable Assemblies { get; set; } = new List(); @@ -17,7 +17,7 @@ public I18NResource(Type resourceType, IEnumerable baseResourceTypes) { _dictionary = new(StringComparer.OrdinalIgnoreCase); ResourceType = resourceType; - BaseResourceTypes = baseResourceTypes; + BaseResourceTypes = baseResourceTypes.ToList(); } public void AddContributor(string cultureName, II18NResourceContributor localizationResourceContributor) @@ -37,4 +37,16 @@ public void AddContributor(string cultureName, II18NResourceContributor localiza return null; } + + public void TryAddBaseResourceTypes() where TBaseResourceType : class + => TryAddBaseResourceTypes(typeof(TBaseResourceType)); + + public void TryAddBaseResourceTypes(params Type[] resourceTypes) + { + foreach (var type in resourceTypes) + { + if (!BaseResourceTypes.Contains(type)) + BaseResourceTypes.Add(type); + } + } } diff --git a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs index cdf1cfc3c..368ce74cc 100644 --- a/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs +++ b/src/Contrib/Dispatcher/Masa.Contrib.Dispatcher.Events.FluentValidation/Middleware/ValidatorMiddleware.cs @@ -8,10 +8,10 @@ namespace Masa.Contrib.Dispatcher.Events; public class ValidatorMiddleware : Middleware where TEvent : IEvent { - private readonly ILogger> _logger; + private readonly ILogger>? _logger; private readonly IEnumerable> _validators; - public ValidatorMiddleware(IEnumerable> validators, ILogger> logger) + public ValidatorMiddleware(IEnumerable> validators, ILogger>? logger = null) { _validators = validators; _logger = logger; @@ -21,7 +21,7 @@ public override async Task HandleAsync(TEvent @event, EventHandlerDelegate next) { var typeName = @event.GetType().FullName; - _logger.LogDebug("----- Validating command {CommandType}", typeName); + _logger?.LogDebug("----- Validating command {CommandType}", typeName); var failures = _validators .Select(v => v.Validate(@event)) @@ -31,7 +31,7 @@ public override async Task HandleAsync(TEvent @event, EventHandlerDelegate next) if (failures.Any()) { - _logger.LogError("Validation errors - {CommandType} - Event: {@Command} - Errors: {@ValidationErrors}", + _logger?.LogError("Validation errors - {CommandType} - Event: {@Command} - Errors: {@ValidationErrors}", typeName, @event, failures); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index b8a9061de..26e7460cb 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -5,6 +5,7 @@ namespace Microsoft.AspNetCore.Builder; +[ExcludeFromCodeCoverage] public static class ApplicationBuilderExtensions { /// diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs index 2f38a92ae..2c78c5618 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/MvcBuilderExtensions.cs @@ -5,6 +5,7 @@ namespace Microsoft.Extensions.DependencyInjection; +[ExcludeFromCodeCoverage] public static class MvcBuilderExtensions { public static IMvcBuilder AddMasaExceptionHandler(this IMvcBuilder builder) diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index 3011e29a8..2ba24e8f2 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -5,6 +5,7 @@ namespace Microsoft.AspNetCore.Builder; +[ExcludeFromCodeCoverage] public class ExceptionHandlerMiddleware { private readonly RequestDelegate _next; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs index 38b9288fe..e1b3be61f 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs @@ -8,6 +8,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters; /// /// Mvc pipeline exception filter to catch global exception /// +[ExcludeFromCodeCoverage] public class MvcGlobalExceptionFilter : IExceptionFilter { private readonly IServiceProvider _serviceProvider; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs index 46318c457..c67692ad4 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/Constant.cs @@ -6,6 +6,4 @@ namespace Masa.Contrib.Exceptions.Internal; internal static class Constant { public const string DEFAULT_HTTP_CONTENT_TYPE = "text/plain; charset=utf-8"; - - // public const string DEFAULT_EXCEPTION_MESSAGE = "An error occur in masa framework."; } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs index b8856b1a6..254435594 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ExceptionExtensions.cs @@ -3,6 +3,7 @@ namespace Masa.Contrib.Exceptions.Internal; +[ExcludeFromCodeCoverage] internal static class ExceptionExtensions { public static int GetHttpStatusCode(this Exception exception) diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs index 4921668cb..136266ae8 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/HttpResponseExtensions.cs @@ -3,6 +3,7 @@ namespace Masa.Contrib.Exceptions.Internal; +[ExcludeFromCodeCoverage] internal static class HttpResponseExtensions { /// diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs index 7ba077a39..0a1bc8546 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs @@ -5,6 +5,7 @@ namespace System; +[ExcludeFromCodeCoverage] internal static class LoggerExtensions { public static void WriteLog( diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ServiceProviderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ServiceProviderExtensions.cs index 280c0694d..6aa173246 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ServiceProviderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/ServiceProviderExtensions.cs @@ -3,6 +3,7 @@ namespace Masa.Contrib.Exceptions.Internal; +[ExcludeFromCodeCoverage] internal static class ServiceProviderExtensions { public static IMasaExceptionHandler? GetMasaExceptionHandler(this IServiceProvider serviceProvider, Type? masaExceptionHandlerType) diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs index 0af2275de..22f4cba33 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs @@ -5,6 +5,7 @@ namespace System; +[ExcludeFromCodeCoverage] public class MasaExceptionContext { public IServiceProvider ServiceProvider { get; set; } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs index 2ca2563c4..3690f0ab0 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionHandlerOptions.cs @@ -5,6 +5,7 @@ namespace System; +[ExcludeFromCodeCoverage] public class MasaExceptionHandlerOptions { public bool CatchAllException { get; set; } = true; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs index 1824bee93..fe7ac8811 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Options/MasaExceptionLogRelationOptions.cs @@ -5,9 +5,10 @@ namespace System; +[ExcludeFromCodeCoverage] public class MasaExceptionLogRelationOptions { - internal Dictionary Mappings { get; } = new(); + private Dictionary Mappings { get; } = new(); public MasaExceptionLogRelationOptions MapLogLevel(LogLevel logLevel) where TException : Exception { diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs index afec35e17..2ea4f9c99 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/DefaultExceptionResult.cs @@ -5,6 +5,7 @@ namespace Microsoft.AspNetCore.Mvc; +[ExcludeFromCodeCoverage] public class DefaultExceptionResult : IActionResult { public string Message { get; set; } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/InternalServerErrorObjectResult.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/InternalServerErrorObjectResult.cs index dbef8d291..fef783dff 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/InternalServerErrorObjectResult.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/InternalServerErrorObjectResult.cs @@ -5,6 +5,7 @@ namespace Microsoft.AspNetCore.Mvc; +[ExcludeFromCodeCoverage] public class InternalServerErrorObjectResult : ObjectResult { public InternalServerErrorObjectResult(object obj) diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/UserFriendlyExceptionResult.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/UserFriendlyExceptionResult.cs index e395fb647..34092fff2 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/UserFriendlyExceptionResult.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Results/UserFriendlyExceptionResult.cs @@ -5,6 +5,7 @@ namespace Microsoft.AspNetCore.Mvc; +[ExcludeFromCodeCoverage] public class UserFriendlyExceptionResult : IActionResult { public string Message { get; set; } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs index c48e9d349..0dbb56ce4 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs @@ -10,6 +10,7 @@ global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; +global using System.Diagnostics.CodeAnalysis; global using System.Net; global using System.Reflection; global using System.Text; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index 162f294b8..9f47b6a1f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -5,6 +5,7 @@ namespace Microsoft.AspNetCore.Builder; +[ExcludeFromCodeCoverage] public static class ApplicationBuilderExtensions { private static bool _isInitialize; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md new file mode 100644 index 000000000..7555a5940 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md @@ -0,0 +1,98 @@ +[中](README.zh-CN.md) | EN + +Provides the ability to parse and obtain Culture, and use it with [I18N](../Masa.Contrib.Globalization.I18N/README.md). Currently, there are three ways to switch languages: + +* URL parameter method: ?culture=en-US, this method has the highest priority, the format is: culture=region code +* Cookies method: call L.SetCulture (region code) method to switch +* Client browser language automatic matching: If neither of the previous two methods are set, it supports automatic matching according to the client browser language. + +## Masa.Contrib.Globalization.I18N.AspNetCore + +Example: + +``` powershell +Install-Package Masa.Contrib.Globalization.I18N.AspNetCore +``` + +### getting Started + +1. Default resource folder structure + +``` structure +- Resources + - I18n + - en-US.json + - zh-CN.json + - supportedCultures.json +``` + +* en-US.json + +``` en-US.json +{ + "Home":"Home", + "Docs":"Docs", + "Blog":"Blog", + "Team":"Team", + "Search":"Search" + "User":{ + "Name":"Name" + } +} +``` + +* zh-CN.json + +``` zh-CN.json +{ + "Home":"Home", + "Docs":"Documents", + "Blog":"Blog", + "Team":"Team", + "Search":"Search", + "User":{ + "Name":"Name" + } +} +``` + +* supportedCultures.json + +``` supportedCultures.json +[ + { + "Culture":"zh-CN", + "DisplayName":"Simplified Chinese", + "Icon": "{Replace-Your-Icon}" + }, + { + "Culture":"en-US", + "DisplayName":"English (United States)", + "Icon": "{Replace-Your-Icon}" + } +] +``` + +2. Register to use I18N, modify `Program.cs` + +``` C# +services.AddI18N(); +``` + +3. Use `Masa.Contrib.Globalization.I18N.AspNetCore` to provide the ability to parse Culture + +``` C# +app.UseI18N(); +``` + +4. How to use I18N + +* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) +* Use `I18N` (**I18N** is a static class) + +Take `I18N` as an example: + +```` C# +var home = I18N.T("Home"); //Get the value of the language corresponding to the key value Home, this method call will return "Home"; +var name = I18N.T("User.Name");//Output: name (support nesting) +```` \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md new file mode 100644 index 000000000..1f982e094 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md @@ -0,0 +1,98 @@ +中 | [EN](README.md) + +提供解析获取Culture的能力,配合[I18N](../Masa.Contrib.Globalization.I18N/README.zh-CN.md)来使用,目前支持三种方式进行切换语言: + +* URL 参数 方式: ?culture=en-US,此方式优先级最高,格式为:culture=区域码 +* Cookies 方式:调用 L.SetCulture(区域码) 方式切换 +* 客户端浏览器语言自动匹配:如果前面两种方式都没有设置,支持自动根据客户端浏览器语言进行匹配。 + +## Masa.Contrib.Globalization.I18N.AspNetCore + +用例: + +``` powershell +Install-Package Masa.Contrib.Globalization.I18N.AspNetCore +``` + +### 入门 + +1. 默认资源文件夹结构 + +``` structure +- Resources + - I18n + - en-US.json + - zh-CN.json + - supportedCultures.json +``` + +* en-US.json + +``` en-US.json +{ + "Home":"Home", + "Docs":"Docs", + "Blog":"Blog", + "Team":"Team", + "Search":"Search" + "User":{ + "Name":"Name" + } +} +``` + +* zh-CN.json + +``` zh-CN.json +{ + "Home":"首页", + "Docs":"文档", + "Blog":"博客", + "Team":"团队", + "Search":"搜索", + "User":{ + "Name":"名称" + } +} +``` + +* supportedCultures.json + +``` supportedCultures.json +[ + { + "Culture":"zh-CN", + "DisplayName":"中文简体", + "Icon": "{Replace-Your-Icon}" + }, + { + "Culture":"en-US", + "DisplayName":"English (United States)", + "Icon": "{Replace-Your-Icon}" + } +] +``` + +2. 注册使用I18N, 修改`Program.cs` + +``` C# +services.AddI18N(); +``` + +3. 使用`Masa.Contrib.Globalization.I18N.AspNetCore`提供解析Culture的能力 + +``` C# +app.UseI18N(); +``` + +4. 如何使用I18N + +* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) +* 使用`I18N` (**I18N**是静态类) + +以`I18N`为例: + +``` C# +var home = I18N.T("Home"); //获取键值Home对应语言的值,此方法调用将返回"首页"; +var name = I18N.T("User.Name");//输出:名称(支持嵌套) +``` \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs index d8cde5c86..4a5e9da4e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs @@ -4,3 +4,4 @@ global using Masa.BuildingBlocks.Globalization.I18N; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Options; +global using System.Diagnostics.CodeAnalysis; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs index d625d27fb..9ace601d0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs @@ -11,13 +11,13 @@ public class DccI18NResourceContributor : II18NResourceContributor public DccI18NResourceContributor( string appId, - string configObject, + string configObjectPrefix, string cultureName, IMasaConfiguration masaConfiguration) { CultureName = cultureName; - _configurationSection = masaConfiguration.ConfigurationApi.Get(appId).GetSection($"{configObject}.{cultureName}"); + _configurationSection = masaConfiguration.ConfigurationApi.Get(appId).GetSection($"{configObjectPrefix}.{cultureName}"); } public string? GetOrNull(string name) diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs new file mode 100644 index 000000000..8b31c8d86 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Dcc; + +public class DccResource +{ + +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index d6156d88e..a0c44c66c 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -7,9 +7,11 @@ namespace Masa.Contrib.Globalization.I18N; public static class I18NOptionsExtensions { + [ExcludeFromCodeCoverage] public static void UseDcc(this I18NOptions i18NOptions) => i18NOptions.UseDcc(Dcc.Internal.Constant.CULTURES_NAME_PREFIX); + [ExcludeFromCodeCoverage] public static void UseDcc( this I18NOptions i18NOptions, string configObjectPrefix) @@ -20,9 +22,13 @@ public static void UseDcc( string appId, string configObjectPrefix) { - I18NResourceResourceConfiguration - .Resources - .Add() - .UseDcc(appId, configObjectPrefix, i18NOptions.SupportedCultures); + i18NOptions.Services.Configure(options => + { + options.Resources.TryAdd(resource => + { + resource.UseDcc(appId, configObjectPrefix, i18NOptions.SupportedCultures); + }); + options.Resources.GetOrNull()?.TryAddBaseResourceTypes(); + }); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs index d5d15b2a8..5ed6ff206 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs @@ -8,7 +8,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public static class I18NResourceExtensions { public static I18NResource UseDcc( - this I18NResource localizationResource, + this I18NResource i18NResource, string appId, string configObjectPrefix, List supportedCultures) @@ -19,8 +19,8 @@ public static I18NResource UseDcc( .Select(supportedCulture => new DccI18NResourceContributor(appId, configObjectPrefix, supportedCulture.Culture, masaConfiguration)).ToList(); foreach (var contributor in contributors) { - localizationResource.AddContributor(contributor.CultureName, contributor); + i18NResource.AddContributor(contributor.CultureName, contributor); } - return localizationResource; + return i18NResource; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs index 5a8d83f3b..6bf9df3d0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs @@ -8,3 +8,4 @@ global using Masa.Contrib.Globalization.I18N.Dcc; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; +global using System.Diagnostics.CodeAnalysis; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index e8ea74351..32e701536 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -11,23 +11,6 @@ public static class I18NResourceExtensions private static IMasaConfiguration? _masaConfiguration; - public static I18NResource AddJsonByEmbeddedResource( - this I18NResource resource, - IEnumerable assemblies, - string resourcesDirectory, - params CultureModel[] supportedCultures) - => resource.AddJsonByEmbeddedResource(assemblies, resourcesDirectory, supportedCultures.ToList()); - - public static I18NResource AddJsonByEmbeddedResource( - this I18NResource resource, - IEnumerable assemblies, - string resourcesDirectory, - IEnumerable supportedCultures) - { - resource.Assemblies = assemblies; - return resource.AddJson(resourcesDirectory, supportedCultures); - } - public static I18NResource AddJson( this I18NResource resource, string resourcesDirectory, diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index edd13605b..210599579 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -87,22 +87,22 @@ private static IServiceCollection AddI18NByFramework(this IServiceCollection ser var assembly = typeof(EmbeddedResourceUtils).Assembly; options.Resources.TryAdd(resource => { - resource.AddJsonByEmbeddedResource(new[] { assembly }, - ContribI18NConstant.DefaultFrameworkResourcePath, + resource.Assemblies = new[] { assembly }; + resource.AddJson(ContribI18NConstant.DefaultFrameworkResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { - resource.AddJsonByEmbeddedResource(new[] { assembly }, - ContribI18NConstant.DefaultFrameworkParameterValidationResourcePath, + resource.Assemblies = new[] { assembly }; + resource.AddJson(ContribI18NConstant.DefaultFrameworkParameterValidationResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { - resource.AddJsonByEmbeddedResource(new[] { assembly }, - ContribI18NConstant.DefaultFrameworkLanguageResourcePath, + resource.Assemblies = new[] { assembly }; + resource.AddJson(ContribI18NConstant.DefaultFrameworkLanguageResourcePath, languageSettings.SupportedCultures); }); }); @@ -150,18 +150,9 @@ private static IServiceCollection AddI18NCore( var localLanguageSettings = cultureSettings; options.Resources.TryAdd(resource => { - if (!assemblies.Any()) - { - resource.AddJson( - localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, - localLanguageSettings.SupportedCultures); - } - else - { - resource.AddJsonByEmbeddedResource(assemblies, - localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, - localLanguageSettings.SupportedCultures); - } + if (assemblies.Any()) resource.Assemblies = assemblies; + resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, + localLanguageSettings.SupportedCultures); }); }); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md index 436e96557..e002e5a47 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md @@ -16,7 +16,7 @@ Install-Package Masa.Contrib.Globalization.I18N ``` structure - Resources - - i18n + - I18n - en-US.json - zh-CN.json - supportedCultures.json @@ -72,25 +72,33 @@ Install-Package Masa.Contrib.Globalization.I18N 2. Register to use I18N, modify `Program.cs` ``` C# -services.AddI18N(options => -{ - options.UseJson();//Use the i18n resource file in the local `Resources/i18n` folder -}); +services.AddI18N(); ``` 3. How to use I18N -``` C# -II18N i18n;//Get from DI -i18n.SetCulture("zh-CN");//Switch the language to zh-CN -var home = i18n.T("Home");//Get the value of the language corresponding to the key value Home, this method call will return "Home"; - -var name = i18n.T("User.Name");//Output: name (support nesting) -``` +* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) +* Use `I18N` (**I18N** is a static class) -4. Get all languages +Take `I18N` as an example: ``` C# -ILanguageProvider languageProvider;//Get from DI -var languages = languageProvider.GetLanguages(); -``` \ No newline at end of file +var home = I18N.T("Home");//Get the value of the language corresponding to the key value Home, this method call will return "Home"; +var name = I18N.T("User.Name");//Output: name (support nesting) +``` + +### Provided by I18N + +* SetCulture (string cultureName): Switch CurrentCulture to zh-CN, and the format of numbers, dates, etc. will also change after it is changed +* SetUiCulture (string cultureName): Switch the interface language (CurrentUICulture) to zh-CN +* GetCultureInfo (): Get CurrentCulture configuration +* GetUiCultureInfo (): Get the interface language (CurrentUICulture) +* T (string name): get the value of the parameter 'name' in the current language + * Returns the value of parameter 'name' when parameter 'name' is not configured in the current language +* T (string name, bool returnKey): get the value of the parameter 'name' in the current language + * returnKey: whether to return the value of the parameter `name` when the parameter 'name' is not configured in the current language +* string T(string name, params object[] arguments): Get the value of the parameter 'name' in the current language, and get the final result according to the incoming parameters + * arguments: parameter value, for example: '{0}' must be greater than 18, then I18N.T("Age",18) should be used + * If the parameter has a format such as number, date, etc., it will change with the change of CurrentCulture +* string T(string name, bool returnKey, params object[] arguments): Get the value of the parameter 'name' in the current language, and get the final result according to the incoming parameters +* GetLanguages(): Get all languages supported by the current system \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md index a4978b33d..4cfd4b180 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md @@ -16,7 +16,7 @@ Install-Package Masa.Contrib.Globalization.I18N ``` structure - Resources - - i18n + - I18n - en-US.json - zh-CN.json - supportedCultures.json @@ -72,25 +72,33 @@ Install-Package Masa.Contrib.Globalization.I18N 2. 注册使用I18N, 修改`Program.cs` ``` C# -services.AddI18N(options => -{ - options.UseJson();//使用本地`Resources/i18n`文件夹下的i18n资源文件 -}); +services.AddI18N(); ``` 3. 如何使用I18N -``` C# -II18N i18n;//从DI获取 -i18n.SetCulture("zh-CN");//将语言切换成zh-CN -var home = i18n.T("Home");//获取键值Home对应语言的值,此方法调用将返回"首页"; - -var name = i18n.T("User.Name");//输出:名称(支持嵌套) -``` +* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) +* 使用`I18N` (**I18N**是静态类) -4. 获取所有语言 +以`I18N`为例: ``` C# -ILanguageProvider languageProvider;//从DI获取 -var languages = languageProvider.GetLanguages(); -``` \ No newline at end of file +var home = I18N.T("Home"); //获取键值Home对应语言的值,此方法调用将返回"首页"; +var name = I18N.T("User.Name");//输出:名称(支持嵌套) +``` + +### I18N提供 + +* SetCulture (string cultureName): 将CurrentCulture切换成zh-CN,它更改后数字、日期等表示格式也随之改变 +* SetUiCulture (string cultureName): 将界面语言(CurrentUICulture)切换成zh-CN +* GetCultureInfo (): 得到CurrentCulture配置 +* GetUiCultureInfo (): 得到界面语言(CurrentUICulture) +* T (string name): 得到参数'name'在当前语言下的值 + * 当参数'name'在当前语言下未配置时返回参数'name'的值 +* T (string name, bool returnKey): 得到参数'name'在当前语言下的值 + * returnKey: 当参数'name'在当前语言下未配置时,是否返回参数`name`的值 +* string T(string name, params object[] arguments): 得到参数'name'在当前语言下的值, 并根据传入参数得到最终的结果 + * arguments: 参数值, 例如: '{0}' 必须大于18, 则应该使用 I18N.T("Age",18) + * 如果参数存在数字、日期等格式,它将随着CurrentCulture的更改更改变 +* string T(string name, bool returnKey, params object[] arguments): 得到参数'name'在当前语言下的值, 并根据传入参数得到最终的结果 +* GetLanguages(): 获取当前系统支持的所有语言 \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json index 2e64a44d7..d66c496e3 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json @@ -17,7 +17,7 @@ "MFARG0016" : "'{0}' 必须是 {1} 个字符,您输入了 {2} 字符。", "MFARG0017" : "'{0}' 必须在 {1} (包含)和 {2} (包含)之间, 您输入了 {3}。", "MFARG0018" : "'{0}' 必须在 {1} (不包含)和 {2} (不包含)之间, 您输入了 {3}。", - "MFARG0019" : "'{0}' 不能为Null和空字符。", + "MFARG0019" : "'{0}' 不能为Null和空。", "MFARG0020" : "'{0}' 总位数不能超过 {1} 位,其中小数部分 {2} 位。您共计输入了 {3} 位数字,其中小数部分{4} 位。", "MFARG0021" : "'{0}' 必须为空。", "MFARG0022" : "'{0}' 必须为Null。", diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index cfb84d4a1..bd48aac23 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -13,5 +13,5 @@ global using Microsoft.Extensions.Localization; global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; -global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; global using System.Reflection; +global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs new file mode 100644 index 000000000..faf1099cc --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs @@ -0,0 +1,49 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Dcc.Tests; + +[TestClass] +public class I18NTest +{ + private const string DEFAULT_RESOURCE = "Resources/I18n"; + + [TestInitialize] + public void Initialize() + { + I18NResourceResourceConfiguration.Resources = new(); + } + + [DataTestMethod] + [DataRow("zh-CN", "吉姆")] + [DataRow("en-US", "JIM")] + public void Test(string cultureName, string expectedValue) + { + var appId = "appid"; + var configObjectPrefix = "Culture"; + var key = "key"; + var services = new ServiceCollection(); + MasaApp.SetServiceCollection(services); + Mock masaConfiguration = new(); + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(new List>() + { + new($"{configObjectPrefix}.{cultureName}:{key}", expectedValue) + }); + var configuration = configurationBuilder.Build(); + masaConfiguration.Setup(config => config.ConfigurationApi.Get(appId)).Returns(configuration); + services.AddSingleton(masaConfiguration.Object); + services.AddI18N(options => + { + options.ResourcesDirectory = DEFAULT_RESOURCE; + }, options => options.UseDcc(appId, configObjectPrefix)); + MasaApp.SetServiceCollection(services); + + var serviceProvider = services.BuildServiceProvider(); + var i18N = serviceProvider.GetService(); + Assert.IsNotNull(i18N); + i18N.SetUiCulture(cultureName); + var value = i18N.T(key); + Assert.AreEqual(expectedValue, value); + } +} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj index c8623c71e..84ef4bbc5 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj @@ -19,10 +19,23 @@ + + + + Always + + + Always + + + Always + + + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json new file mode 100644 index 000000000..a297596b1 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json @@ -0,0 +1,3 @@ +{ + "Name": "Jim" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json new file mode 100644 index 000000000..f6e4fbb29 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json @@ -0,0 +1,10 @@ +[ + { + "Culture": "zh-CN", + "DisplayName": "中文简体" + }, + { + "Culture": "en-US", + "DisplayName": "English (United States)" + } +] \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json new file mode 100644 index 000000000..cc6cfb637 --- /dev/null +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json @@ -0,0 +1,3 @@ +{ + "Name": "吉姆" +} \ No newline at end of file diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs index f5c8cbc4c..a2034b139 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs @@ -1,3 +1,10 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Globalization.I18N; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using Moq; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs index 8a05691e0..241a54711 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs @@ -24,7 +24,7 @@ public void TestLocalization(string cultureName, string expectedValue) services.TestAddI18N(); var serviceProvider = services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); - i18N.SetCulture(cultureName); + i18N.SetUiCulture(cultureName); var value = i18N["Name"]; Assert.AreEqual(expectedValue, value); value = i18N.T("Name"); @@ -42,7 +42,7 @@ public void TestLocalization2(string cultureName, string expectedValue) builder.Services.TestAddI18N(DEFAULT_RESOURCE); var serviceProvider = builder.Services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); - i18N.SetCulture(cultureName); + i18N.SetUiCulture(cultureName); var value = i18N["Name"]; Assert.AreEqual(expectedValue, value); value = i18N.T("Name"); @@ -59,7 +59,7 @@ public void TestLocalization3(string cultureName, string expectedValue) builder.Services.AddI18N(DEFAULT_RESOURCE); var serviceProvider = builder.Services.BuildServiceProvider(); var i18N = serviceProvider.GetRequiredService(); - i18N.SetCulture(cultureName); + i18N.SetUiCulture(cultureName); var value = i18N["Name"]; Assert.AreEqual(expectedValue, value); value = i18N.T("Name"); diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj index c221d710c..923af21a8 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj @@ -29,14 +29,8 @@ - - + Always - - - - - From 60aec79d6a9eabf120089659c772a2e354a9d0a0 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 10 Nov 2022 09:58:56 +0800 Subject: [PATCH 28/38] fix: Fix unit test issues --- .../MasaArgumentExceptionTest.cs | 4 ++-- .../DistributedCacheClientTest.cs | 4 ++-- .../TestBase.cs | 2 +- .../DccTest.cs | 6 +++--- .../Extensions/ServiceCollectionExtensions.cs | 8 ++------ .../IntegrationEventBusTest.cs | 4 ++-- .../DispatcherOptionTest.cs | 20 +++++++++---------- .../IntegrationEventBusTest.cs | 4 ++-- .../AssemblyResolutionTests.cs | 6 +++--- .../StorageTest.cs | 4 ++-- .../TestALiYunStorageOptions.cs | 4 ++-- 11 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs index 2d28ebc86..5bf2cdc54 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs @@ -19,8 +19,8 @@ public void TestThrowIfNull() } catch (MasaArgumentException ex) { - Assert.AreEqual(Masa.BuildingBlocks.Data.Constants.ErrorCode.NULL_VALIDATOR, ex.ErrorCode); - Assert.AreEqual("Value cannot be null. (Parameter '{0}')", ex.ErrorMessage); + Assert.AreEqual(Data.Constants.ErrorCode.NOT_NULL_VALIDATOR, ex.ErrorCode); + Assert.AreEqual("'{0}' must not be empty.", ex.ErrorMessage); } } } diff --git a/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/DistributedCacheClientTest.cs b/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/DistributedCacheClientTest.cs index d802b67c4..d40a7f98c 100644 --- a/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/DistributedCacheClientTest.cs +++ b/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/DistributedCacheClientTest.cs @@ -528,7 +528,7 @@ public async Task TestHashIncrementAndValueLessThan1Async(string key, int value) { await _distributedCacheClient.RemoveAsync(key); - await Assert.ThrowsExceptionAsync(async () + await Assert.ThrowsExceptionAsync(async () => await _distributedCacheClient.HashIncrementAsync(key, value)); } @@ -555,7 +555,7 @@ public async Task TestHashDecrementAndValueLessThan1Async(string key, long value { await _distributedCacheClient.RemoveAsync(key); - await Assert.ThrowsExceptionAsync(async () + await Assert.ThrowsExceptionAsync(async () => await _distributedCacheClient.HashDecrementAsync(key, value)); } diff --git a/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs b/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs index d82a761b8..1c2b1fa39 100644 --- a/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs +++ b/src/Contrib/Caching/Distributed/Tests/Masa.Contrib.Caching.Distributed.StackExchangeRedis.Tests/TestBase.cs @@ -13,7 +13,7 @@ protected static RedisConfigurationOptions GetConfigurationOptions() { GlobalCacheOptions = new CacheOptions() { - CacheKeyType = CacheKeyType.TypeName + CacheKeyType = CacheKeyType.None } }; redisConfigurationOptions.Servers.Add(new RedisServerOptions()); diff --git a/src/Contrib/Configuration/ConfigurationApi/Tests/Masa.Contrib.Configuration.ConfigurationApi.Dcc.Tests/DccTest.cs b/src/Contrib/Configuration/ConfigurationApi/Tests/Masa.Contrib.Configuration.ConfigurationApi.Dcc.Tests/DccTest.cs index c22a537cf..6ded36981 100644 --- a/src/Contrib/Configuration/ConfigurationApi/Tests/Masa.Contrib.Configuration.ConfigurationApi.Dcc.Tests/DccTest.cs +++ b/src/Contrib/Configuration/ConfigurationApi/Tests/Masa.Contrib.Configuration.ConfigurationApi.Dcc.Tests/DccTest.cs @@ -524,7 +524,7 @@ public void TestComplementAndCheckDccConfigurationOptionByCustomerDccOptions() public void TestComplementAndCheckDccConfigurationOptionByManageServiceAddressIsEmpty() { DccOptions dccOptions = new DccOptions(); - Assert.ThrowsException(() => + Assert.ThrowsException(() => { MasaConfigurationExtensions.ComplementAndCheckDccConfigurationOption(_masaConfigurationBuilder.Object, dccOptions); }); @@ -537,7 +537,7 @@ public void TestComplementAndCheckDccConfigurationOptionByRedisServersIsEmpty() { ManageServiceAddress = nameof(DccOptions.ManageServiceAddress), }; - Assert.ThrowsException(() => + Assert.ThrowsException(() => { MasaConfigurationExtensions.ComplementAndCheckDccConfigurationOption(_masaConfigurationBuilder.Object, dccOptions); }); @@ -599,7 +599,7 @@ public void TestComplementAndCheckDccConfigurationOptionByAppIdIsEmpty() } } }; - Assert.ThrowsException(() => + Assert.ThrowsException(() => { MasaConfigurationExtensions.ComplementAndCheckDccConfigurationOption(_masaConfigurationBuilder.Object, dccOptions); }); diff --git a/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs index 067d57562..3457e293c 100644 --- a/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Configuration/Masa.Contrib.Configuration/Extensions/ServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. // ReSharper disable once CheckNamespace + namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions @@ -135,12 +136,7 @@ public static IServiceCollection AddMasaConfiguration( configurationBuilder.Sources.Clear(); configurationBuilder.AddConfiguration(masaConfiguration); - if (sourceConfiguration == null) - { - var configurationManager = new ConfigurationManager(); - configurationBuilder.AddConfiguration(configurationBuilder.Build()); - services.AddSingleton(_ => configurationManager); - } + if (sourceConfiguration == null) services.AddSingleton(_ => configurationBuilder.Build()); return services; } diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/IntegrationEventBusTest.cs b/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/IntegrationEventBusTest.cs index d1a7101e9..0a54e9bed 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/IntegrationEventBusTest.cs +++ b/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/IntegrationEventBusTest.cs @@ -44,11 +44,11 @@ public void TestDispatcherOption() var services = new ServiceCollection(); DispatcherOptions options; - Assert.ThrowsException(() => + Assert.ThrowsException(() => { options = new DispatcherOptions(services, null!); }); - Assert.ThrowsException(() => + Assert.ThrowsException(() => { options = new DispatcherOptions(services, Array.Empty()); }); diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/DispatcherOptionTest.cs b/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/DispatcherOptionTest.cs index 79a51335e..0005cacb2 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/DispatcherOptionTest.cs +++ b/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/DispatcherOptionTest.cs @@ -22,7 +22,7 @@ public void TestSetLocalRetryTimes() _options.LocalRetryTimes = 5; Assert.IsTrue(_options.LocalRetryTimes == 5); - Assert.ThrowsException(() => _options.LocalRetryTimes = 0); + Assert.ThrowsException(() => _options.LocalRetryTimes = 0); } [TestMethod] @@ -32,7 +32,7 @@ public void TestSetMaxRetryTimes() _options.MaxRetryTimes = 5; Assert.IsTrue(_options.MaxRetryTimes == 5); - Assert.ThrowsException(() => _options.MaxRetryTimes = 0); + Assert.ThrowsException(() => _options.MaxRetryTimes = 0); } [TestMethod] @@ -42,7 +42,7 @@ public void TestSetFailedRetryInterval() _options.FailedRetryInterval = 5; Assert.IsTrue(_options.FailedRetryInterval == 5); - Assert.ThrowsException(() => _options.FailedRetryInterval = 0); + Assert.ThrowsException(() => _options.FailedRetryInterval = 0); } [TestMethod] @@ -52,7 +52,7 @@ public void TestSetMinimumRetryInterval() _options.MinimumRetryInterval = 5; Assert.IsTrue(_options.MinimumRetryInterval == 5); - Assert.ThrowsException(() => _options.MinimumRetryInterval = 0); + Assert.ThrowsException(() => _options.MinimumRetryInterval = 0); } [TestMethod] @@ -62,7 +62,7 @@ public void TestSetLocalFailedRetryInterval() _options.LocalFailedRetryInterval = 5; Assert.IsTrue(_options.LocalFailedRetryInterval == 5); - Assert.ThrowsException(() => _options.LocalFailedRetryInterval = -1); + Assert.ThrowsException(() => _options.LocalFailedRetryInterval = -1); } [TestMethod] @@ -72,7 +72,7 @@ public void TestSetRetryBatchSize() _options.RetryBatchSize = 5; Assert.IsTrue(_options.RetryBatchSize == 5); - Assert.ThrowsException(() => _options.RetryBatchSize = -1); + Assert.ThrowsException(() => _options.RetryBatchSize = -1); } [TestMethod] @@ -82,7 +82,7 @@ public void TestSetCleaningLocalQueueExpireInterval() _options.CleaningLocalQueueExpireInterval = 5; Assert.IsTrue(_options.CleaningLocalQueueExpireInterval == 5); - Assert.ThrowsException(() => _options.CleaningLocalQueueExpireInterval = 0); + Assert.ThrowsException(() => _options.CleaningLocalQueueExpireInterval = 0); } [TestMethod] @@ -92,7 +92,7 @@ public void TestSetCleaningExpireInterval() _options.CleaningExpireInterval = 5; Assert.IsTrue(_options.CleaningExpireInterval == 5); - Assert.ThrowsException(() => _options.CleaningExpireInterval = 0); + Assert.ThrowsException(() => _options.CleaningExpireInterval = 0); } [TestMethod] @@ -102,7 +102,7 @@ public void TestSetPublishedExpireTime() _options.PublishedExpireTime = 24 * 3 * 3600; Assert.IsTrue(_options.PublishedExpireTime == 24 * 3 * 3600); - Assert.ThrowsException(() => _options.PublishedExpireTime = 0); + Assert.ThrowsException(() => _options.PublishedExpireTime = 0); } [TestMethod] @@ -112,7 +112,7 @@ public void TestSetDeleteBatchCount() _options.DeleteBatchCount = 100; Assert.IsTrue(_options.DeleteBatchCount == 100); - Assert.ThrowsException(() => _options.DeleteBatchCount = 0); + Assert.ThrowsException(() => _options.DeleteBatchCount = 0); } [TestMethod] diff --git a/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/IntegrationEventBusTest.cs b/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/IntegrationEventBusTest.cs index d411abea5..6249ecfb0 100644 --- a/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/IntegrationEventBusTest.cs +++ b/src/Contrib/Dispatcher/IntegrationEvents/Tests/Masa.Contrib.Dispatcher.IntegrationEvents.Tests/IntegrationEventBusTest.cs @@ -49,11 +49,11 @@ public void TestDispatcherOption() var services = new ServiceCollection(); DispatcherOptions options; - Assert.ThrowsException(() => + Assert.ThrowsException(() => { options = new DispatcherOptions(services, null!); }); - Assert.ThrowsException(() => + Assert.ThrowsException(() => { options = new DispatcherOptions(services, Array.Empty()); }); diff --git a/src/Contrib/Dispatcher/Tests/Masa.Contrib.Dispatcher.Events.Tests/AssemblyResolutionTests.cs b/src/Contrib/Dispatcher/Tests/Masa.Contrib.Dispatcher.Events.Tests/AssemblyResolutionTests.cs index 104ff7d80..d2ca1889f 100644 --- a/src/Contrib/Dispatcher/Tests/Masa.Contrib.Dispatcher.Events.Tests/AssemblyResolutionTests.cs +++ b/src/Contrib/Dispatcher/Tests/Masa.Contrib.Dispatcher.Events.Tests/AssemblyResolutionTests.cs @@ -24,7 +24,7 @@ public void TestAddNullAssembly() { var services = new ServiceCollection(); services.AddLogging(loggingBuilder => loggingBuilder.AddConsole()); - Assert.ThrowsException(() => + Assert.ThrowsException(() => { Assembly[] assemblies = null!; services.AddEventBus(assemblies!); @@ -36,7 +36,7 @@ public void TestAddEmptyAssembly() { var services = new ServiceCollection(); services.AddLogging(loggingBuilder => loggingBuilder.AddConsole()); - Assert.ThrowsException(() => + Assert.ThrowsException(() => { services.AddEventBus(Array.Empty()); }); @@ -47,7 +47,7 @@ public void TestEventBusByAddNullAssembly() { var services = new ServiceCollection(); services.AddLogging(loggingBuilder => loggingBuilder.AddConsole()); - Assert.ThrowsException(() => + Assert.ThrowsException(() => { services.AddTestEventBus(null!, ServiceLifetime.Scoped); }); diff --git a/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/StorageTest.cs b/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/StorageTest.cs index 0cc17c9eb..df7688927 100644 --- a/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/StorageTest.cs +++ b/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/StorageTest.cs @@ -19,7 +19,7 @@ public void TestAddAliyunStorageAndNotAddConfigurationReturnClientIsNotNull() public void TestAddAliyunStorageByEmptySectionReturnThrowArgumentException() { var services = new ServiceCollection(); - Assert.ThrowsException(() => services.AddAliyunStorage(string.Empty)); + Assert.ThrowsException(() => services.AddAliyunStorage(string.Empty)); } [TestMethod] @@ -226,7 +226,7 @@ public void TestAddAliyunStorageAndNullALiYunStorageOptionsReturnThrowArgumentNu [TestMethod] public void TestAddAliyunStorageByEmptyAccessKeyIdReturnThrowArgumentNullException() { - Assert.ThrowsException(() => new AliyunStorageOptions(null!, null!, null!)); + Assert.ThrowsException(() => new AliyunStorageOptions(null!, null!, null!)); } [TestMethod] diff --git a/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/TestALiYunStorageOptions.cs b/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/TestALiYunStorageOptions.cs index 4861e61f6..7744fe0e6 100644 --- a/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/TestALiYunStorageOptions.cs +++ b/src/Contrib/Storage/ObjectStorage/Tests/Masa.Contrib.Storage.ObjectStorage.Aliyun.Tests/TestALiYunStorageOptions.cs @@ -24,7 +24,7 @@ public void TestErrorParameterThrowArgumentException( string roleSessionName, string parameterName) { - Assert.ThrowsException(() => + Assert.ThrowsException(() => new AliyunStorageOptions(accessKeyId, accessKeySecret, regionId, roleArn, roleSessionName), $"{parameterName} cannot be empty"); } @@ -73,7 +73,7 @@ public void TestErrorTemporaryCredentialsCacheKeyReturnThrowArgumentException( string temporaryCredentialsCacheKeyName) { var options = new AliyunStorageOptions("AccessKeyId", "AccessKeySecret", HANG_ZHOUE_PUBLIC_ENDPOINT, "RoleArn", "RoleSessionName"); - Assert.ThrowsException(() => + Assert.ThrowsException(() => options.SetTemporaryCredentialsCacheKey(temporaryCredentialsCacheKey), $"{temporaryCredentialsCacheKeyName} cannot be empty"); } From 10d39ab2206561a19c977ea6fbfc5c43c0e16cd9 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 10 Nov 2022 11:30:09 +0800 Subject: [PATCH 29/38] rename: I18N -> I18n --- Masa.Framework.sln | 12 ++++++------ .../Masa.BuildingBlocks.Exceptions.csproj | 2 +- .../MasaArgumentException.cs | 1 + .../MasaValidatorException.cs | 1 + .../Constant.cs | 0 .../CultureModel.cs | 0 .../CultureSettings.cs | 0 .../DefaultLanguageProvider.cs | 0 .../I18N.cs | 2 +- .../I18NOfT.cs | 4 ++-- .../I18NResource.cs | 0 .../I18NResourceDictionary.cs | 0 .../I18NResourceResourceConfiguration.cs | 0 .../II18N.cs | 0 .../II18NOfT.cs | 0 .../II18NResourceContributor.cs | 0 .../ILanguageProvider.cs | 0 .../InheritResourceAttribute.cs | 0 .../LanguageInfo.cs | 0 .../Masa.BuildingBlocks.Globalization.I18n.csproj} | 1 + .../Options/I18NOptions.cs | 0 .../Options/MasaI18NOptions.cs | 0 .../Resources/DefaultResource.cs | 0 .../Resources/MasaFrameworkResource.cs | 0 .../Resources/MasaLanguageResource.cs | 0 .../Resources/MasaParameterValidationResource.cs | 0 .../_Imports.cs | 0 .../Handlers/MvcGlobalExceptionFilter.cs | 4 ++-- .../Masa.Contrib.Exceptions.csproj | 4 ++-- .../Extensions/ApplicationBuilderExtensions.cs | 0 ...asa.Contrib.Globalization.I18n.AspNetCore.csproj} | 2 +- .../README.md | 8 ++++---- .../README.zh-CN.md | 8 ++++---- .../_Imports.cs | 0 .../DccI18NResourceContributor.cs | 2 +- .../DccResource.cs | 4 ++-- .../Extensions/I18NOptionsExtensions.cs | 2 +- .../Extensions/I18NResourceExtensions.cs | 0 .../Internal/Constant.cs | 2 +- .../Masa.Contrib.Globalization.I18n.Dcc.csproj} | 4 ++-- .../_Imports.cs | 2 +- .../Constant.cs | 2 +- .../EmbeddedResourceUtils.cs | 2 +- .../Extensions/I18NResourceExtensions.cs | 0 .../Extensions/ServiceCollectionExtensions.cs | 2 +- .../FileConfigurationProvider.cs | 2 +- .../Internal/CultureUtils.cs | 2 +- .../Internal/PathUtils.cs | 2 +- .../Json/JsonConfigurationProvider.cs | 2 +- .../Json/JsonConfigurationProviderByEmbedded.cs | 2 +- .../Json/JsonConfigurationSource.cs | 2 +- .../Json/JsonConfigurationSourceByEmbedded.cs | 2 +- .../LocalI18NResourceContributor.cs | 0 .../Masa.Contrib.Globalization.I18n.csproj} | 2 +- .../README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- .../Resources/I18n/Framework/Languages/en-US.json | 0 .../Resources/I18n/Framework/Languages/zh-CN.json | 0 .../I18n/Framework/ParameterValidations/en-US.json | 0 .../I18n/Framework/ParameterValidations/zh-CN.json | 0 .../Resources/I18n/Framework/en-US.json | 0 .../Resources/I18n/Framework/zh-CN.json | 0 .../_Imports.cs | 8 ++++---- .../I18NTest.cs | 2 +- ...Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj} | 3 ++- .../Resources/I18n/en-US.json | 0 .../Resources/I18n/supportedCultures.json | 0 .../Resources/I18n/zh-CN.json | 0 .../_Imports.cs | 0 .../I18NTest.cs | 2 +- .../Masa.Contrib.Globalization.I18n.Tests.csproj} | 3 ++- .../Resources/I18n/en-US.json | 0 .../Resources/I18n/supportedCultures.json | 0 .../Resources/I18n/zh-CN.json | 0 .../_Imports.cs | 0 75 files changed, 59 insertions(+), 54 deletions(-) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Constant.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/CultureModel.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/CultureSettings.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/DefaultLanguageProvider.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/I18N.cs (99%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/I18NOfT.cs (97%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/I18NResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/I18NResourceDictionary.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/I18NResourceResourceConfiguration.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/II18N.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/II18NOfT.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/II18NResourceContributor.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/ILanguageProvider.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/InheritResourceAttribute.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/LanguageInfo.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj => Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj} (82%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Options/I18NOptions.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Options/MasaI18NOptions.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/DefaultResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/MasaFrameworkResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/MasaLanguageResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/MasaParameterValidationResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/_Imports.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/Extensions/ApplicationBuilderExtensions.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj => Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj} (89%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/README.md (88%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/README.zh-CN.md (87%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/_Imports.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/DccI18NResourceContributor.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/DccResource.cs (77%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/Extensions/I18NOptionsExtensions.cs (96%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/Extensions/I18NResourceExtensions.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/Internal/Constant.cs (81%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj => Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj} (79%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/_Imports.cs (90%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Constant.cs (95%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/EmbeddedResourceUtils.cs (97%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Extensions/I18NResourceExtensions.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Extensions/ServiceCollectionExtensions.cs (99%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/FileConfigurationProvider.cs (98%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Internal/CultureUtils.cs (96%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Internal/PathUtils.cs (92%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationProvider.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationProviderByEmbedded.cs (97%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationSource.cs (95%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationSourceByEmbedded.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/LocalI18NResourceContributor.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj => Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj} (91%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/README.md (97%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/README.zh-CN.md (96%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Resources/I18n/Framework/Languages/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Resources/I18n/Framework/Languages/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Resources/I18n/Framework/ParameterValidations/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Resources/I18n/Framework/ParameterValidations/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Resources/I18n/Framework/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Resources/I18n/Framework/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/_Imports.cs (80%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests => Masa.Contrib.Globalization.I18n.Dcc.Tests}/I18NTest.cs (97%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj => Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj} (92%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests => Masa.Contrib.Globalization.I18n.Dcc.Tests}/Resources/I18n/en-US.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests => Masa.Contrib.Globalization.I18n.Dcc.Tests}/Resources/I18n/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests => Masa.Contrib.Globalization.I18n.Dcc.Tests}/Resources/I18n/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests => Masa.Contrib.Globalization.I18n.Dcc.Tests}/_Imports.cs (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests => Masa.Contrib.Globalization.I18n.Tests}/I18NTest.cs (98%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj => Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj} (92%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests => Masa.Contrib.Globalization.I18n.Tests}/Resources/I18n/en-US.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests => Masa.Contrib.Globalization.I18n.Tests}/Resources/I18n/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests => Masa.Contrib.Globalization.I18n.Tests}/Resources/I18n/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests => Masa.Contrib.Globalization.I18n.Tests}/_Imports.cs (100%) diff --git a/Masa.Framework.sln b/Masa.Framework.sln index e1f1f013a..b66626a33 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -557,7 +557,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalizat EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalization", "{5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Globalization.I18N", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18N\Masa.BuildingBlocks.Globalization.I18N.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Globalization.I18n", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18n\Masa.BuildingBlocks.Globalization.I18n.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A}" EndProject @@ -599,15 +599,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.Da EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.DaprStarter.AspNetCore.Tests", "src\Contrib\Development\Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests.csproj", "{DD899DC4-A2B7-4C7B-A644-EDB56A61145C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N\Masa.Contrib.Globalization.I18N.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n\Masa.Contrib.Globalization.I18n.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D2E598D5-5E44-4275-AF03-4BAD07A0E13B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Tests\Masa.Contrib.Globalization.I18N.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18n.Tests\Masa.Contrib.Globalization.I18n.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Dcc\Masa.Contrib.Globalization.I18N.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n.Dcc\Masa.Contrib.Globalization.I18n.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18n.Dcc.Tests\Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exception", "Exception", "{84F366D3-6E9A-4101-AEC0-287CBA6984A8}" EndProject @@ -619,7 +619,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Exceptions", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Exceptions.Tests", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions.Tests\Masa.BuildingBlocks.Exceptions.Tests.csproj", "{921DCAAC-3146-4EDB-891C-D76089E4A451}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.AspNetCore\Masa.Contrib.Globalization.I18N.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n.AspNetCore\Masa.Contrib.Globalization.I18n.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Dispatcher.Events.FluentValidation", "src\Contrib\Dispatcher\Masa.Contrib.Dispatcher.Events.FluentValidation\Masa.Contrib.Dispatcher.Events.FluentValidation.csproj", "{66B1723A-D578-418C-B21C-2C3B5CBD1180}" EndProject diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj index af9c871f2..63c029362 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs index 1b2ea778a..bd49b1fba 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -5,6 +5,7 @@ namespace System; +[Serializable] public class MasaArgumentException : MasaException { protected string? ParamName { get; } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs index f1c4e9ee4..a8fb1c025 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs @@ -5,6 +5,7 @@ namespace System; +[Serializable] public class MasaValidatorException : MasaArgumentException { public MasaValidatorException(string message) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Constant.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Constant.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureModel.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureModel.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureSettings.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureSettings.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs similarity index 99% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs index 254effc2a..8365db955 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs @@ -3,7 +3,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public static class I18N +public static class I18n { private static readonly IServiceProvider _serviceProvider = MasaApp.RootServiceProvider; private static readonly II18N _i18N = InitI18N(); diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NOfT.cs similarity index 97% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NOfT.cs index 673e55ac2..747bdb076 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NOfT.cs @@ -3,7 +3,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public class I18NOfT : II18N +public class I18nOfT : II18N { private readonly I18NResource? _resource; private readonly List _baseResources; @@ -16,7 +16,7 @@ public class I18NOfT : II18N public string? this[string name, bool returnKey, params object[] arguments] => T(name, returnKey, arguments); - public I18NOfT() + public I18nOfT() { _resource = I18NResourceResourceConfiguration.Resources.GetOrNull(); diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceDictionary.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceDictionary.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceResourceConfiguration.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceResourceConfiguration.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18N.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18N.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NResourceContributor.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NResourceContributor.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/ILanguageProvider.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/ILanguageProvider.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/InheritResourceAttribute.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/InheritResourceAttribute.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/LanguageInfo.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/LanguageInfo.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj similarity index 82% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj index b3d41f5ba..198661ec9 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + Masa.BuildingBlocks.Globalization.I18N diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/I18NOptions.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/I18NOptions.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18NOptions.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18NOptions.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/DefaultResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/DefaultResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaFrameworkResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaFrameworkResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaParameterValidationResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaParameterValidationResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/_Imports.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/_Imports.cs diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs index e1b3be61f..f2f4a3ae4 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs @@ -15,13 +15,13 @@ public class MvcGlobalExceptionFilter : IExceptionFilter private readonly IMasaExceptionHandler? _masaExceptionHandler; private readonly MasaExceptionHandlerOptions _options; private readonly MasaExceptionLogRelationOptions _logRelationOptions; - private readonly I18NOfT? _frameworkI18N; + private readonly I18nOfT? _frameworkI18N; private readonly ILogger? _logger; public MvcGlobalExceptionFilter(IServiceProvider serviceProvider, IOptions options, IOptions logRelationOptions, - I18NOfT? frameworkI18N = null, + I18nOfT? frameworkI18N = null, ILogger? logger = null) { _serviceProvider = serviceProvider; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj index 0d5372eb1..bb1f4fc8c 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj similarity index 89% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj index 3da5d7f8d..ef26fdad6 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md similarity index 88% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md index 7555a5940..856b545a3 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md @@ -1,17 +1,17 @@ [中](README.zh-CN.md) | EN -Provides the ability to parse and obtain Culture, and use it with [I18N](../Masa.Contrib.Globalization.I18N/README.md). Currently, there are three ways to switch languages: +Provides the ability to parse and obtain Culture, and use it with [I18N](../Masa.Contrib.Globalization.I18n/README.md). Currently, there are three ways to switch languages: * URL parameter method: ?culture=en-US, this method has the highest priority, the format is: culture=region code * Cookies method: call L.SetCulture (region code) method to switch * Client browser language automatic matching: If neither of the previous two methods are set, it supports automatic matching according to the client browser language. -## Masa.Contrib.Globalization.I18N.AspNetCore +## Masa.Contrib.Globalization.I18n.AspNetCore Example: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N.AspNetCore +Install-Package Masa.Contrib.Globalization.I18n.AspNetCore ``` ### getting Started @@ -79,7 +79,7 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore services.AddI18N(); ``` -3. Use `Masa.Contrib.Globalization.I18N.AspNetCore` to provide the ability to parse Culture +3. Use `Masa.Contrib.Globalization.I18n.AspNetCore` to provide the ability to parse Culture ``` C# app.UseI18N(); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md similarity index 87% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md index 1f982e094..9ba770682 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md @@ -1,17 +1,17 @@ 中 | [EN](README.md) -提供解析获取Culture的能力,配合[I18N](../Masa.Contrib.Globalization.I18N/README.zh-CN.md)来使用,目前支持三种方式进行切换语言: +提供解析获取Culture的能力,配合[I18N](../Masa.Contrib.Globalization.I18n/README.zh-CN.md)来使用,目前支持三种方式进行切换语言: * URL 参数 方式: ?culture=en-US,此方式优先级最高,格式为:culture=区域码 * Cookies 方式:调用 L.SetCulture(区域码) 方式切换 * 客户端浏览器语言自动匹配:如果前面两种方式都没有设置,支持自动根据客户端浏览器语言进行匹配。 -## Masa.Contrib.Globalization.I18N.AspNetCore +## Masa.Contrib.Globalization.I18n.AspNetCore 用例: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N.AspNetCore +Install-Package Masa.Contrib.Globalization.I18n.AspNetCore ``` ### 入门 @@ -79,7 +79,7 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore services.AddI18N(); ``` -3. 使用`Masa.Contrib.Globalization.I18N.AspNetCore`提供解析Culture的能力 +3. 使用`Masa.Contrib.Globalization.I18n.AspNetCore`提供解析Culture的能力 ``` C# app.UseI18N(); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/_Imports.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/_Imports.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18NResourceContributor.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18NResourceContributor.cs index 9ace601d0..b6063df0e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18NResourceContributor.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc; +namespace Masa.Contrib.Globalization.I18n.Dcc; public class DccI18NResourceContributor : II18NResourceContributor { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs similarity index 77% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs index 8b31c8d86..032c37d79 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc; +namespace Masa.Contrib.Globalization.I18n.Dcc; public class DccResource { - + } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NOptionsExtensions.cs similarity index 96% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NOptionsExtensions.cs index a0c44c66c..d58f2b33e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NOptionsExtensions.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; public static class I18NOptionsExtensions { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NResourceExtensions.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NResourceExtensions.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs similarity index 81% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs index 15f510c3b..375837e3e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc.Internal; +namespace Masa.Contrib.Globalization.I18n.Dcc.Internal; internal static class Constant { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj similarity index 79% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj index 25efebcc9..900830af2 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj @@ -7,9 +7,9 @@ - + - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs similarity index 90% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs index 6bf9df3d0..f67ae25c4 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs @@ -5,7 +5,7 @@ global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Globalization.I18N; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; -global using Masa.Contrib.Globalization.I18N.Dcc; +global using Masa.Contrib.Globalization.I18n.Dcc; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using System.Diagnostics.CodeAnalysis; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs index 7f2f3df55..00981fb67 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; public static class Constant { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs similarity index 97% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs index 606ca13de..f3cec8f26 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; public class EmbeddedResourceUtils { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18NResourceExtensions.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18NResourceExtensions.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs similarity index 99% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs index 210599579..af3e8b463 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs @@ -141,7 +141,7 @@ private static IServiceCollection AddI18NCore( CultureSettings cultureSettings) where TResource : class { services.AddOptions(); - services.TryAddTransient(typeof(II18N<>), typeof(I18NOfT<>)); + services.TryAddTransient(typeof(II18N<>), typeof(I18nOfT<>)); services.TryAddSingleton(); services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs similarity index 98% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs index 7db348aad..f1c55a8c0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; public abstract class FileConfigurationProvider : ConfigurationProvider { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs similarity index 96% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs index dfe5a0b5b..a689691e7 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Internal; +namespace Masa.Contrib.Globalization.I18n.Internal; internal static class CultureUtils { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs similarity index 92% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs index a1f299af1..43d62d7e2 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; internal static class PathUtils { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs index b93501aaa..77c3a5879 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationProvider : FileConfigurationProvider { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs similarity index 97% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs index 6e8a0f41f..dae33b74a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Configuration.Json; -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationProviderByEmbedded : ConfigurationProvider { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs index 2a941b8c0..98430e83e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationSource : IConfigurationSource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs index 591189cbe..074e1277b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationSourceByEmbedded : IConfigurationSource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/LocalI18NResourceContributor.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/LocalI18NResourceContributor.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj similarity index 91% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj index 587bc9dc4..8bf37049e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md similarity index 97% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md index e002e5a47..39232c3ce 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md @@ -2,12 +2,12 @@ Provide [Internationalization](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization) capability -## Masa.Contrib.Globalization.I18N +## Masa.Contrib.Globalization.I18n Example: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N +Install-Package Masa.Contrib.Globalization.I18n ``` ### getting Started diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md similarity index 96% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md index 4cfd4b180..1b8238ab5 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md @@ -2,12 +2,12 @@ 提供[国际化](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization)能力 -## Masa.Contrib.Globalization.I18N +## Masa.Contrib.Globalization.I18n 用例: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N +Install-Package Masa.Contrib.Globalization.I18n ``` ### 入门 diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs similarity index 80% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs index bd48aac23..4de763b05 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs @@ -4,9 +4,9 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Globalization.I18N; -global using Masa.Contrib.Globalization.I18N; -global using Masa.Contrib.Globalization.I18N.Internal; -global using Masa.Contrib.Globalization.I18N.Json; +global using Masa.Contrib.Globalization.I18n; +global using Masa.Contrib.Globalization.I18n.Internal; +global using Masa.Contrib.Globalization.I18n.Json; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; @@ -14,4 +14,4 @@ global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; global using System.Reflection; -global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; +global using ContribI18NConstant = Masa.Contrib.Globalization.I18n.Constant; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18NTest.cs similarity index 97% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18NTest.cs index faf1099cc..a64a2d731 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18NTest.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc.Tests; +namespace Masa.Contrib.Globalization.I18n.Dcc.Tests; [TestClass] public class I18NTest diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj similarity index 92% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj index 84ef4bbc5..85a75ce83 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj @@ -5,6 +5,7 @@ enable false enable + Masa.Contrib.Globalization.I18n.Dcc.Tests @@ -23,7 +24,7 @@ - + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/_Imports.cs similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/_Imports.cs diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18NTest.cs similarity index 98% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18NTest.cs index 241a54711..501bdaff7 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18NTest.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Tests; +namespace Masa.Contrib.Globalization.I18n.Tests; [TestClass] public class I18NTest diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj similarity index 92% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj index 923af21a8..7c7c64021 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj @@ -5,6 +5,7 @@ enable false enable + Masa.Contrib.Globalization.I18n.Tests @@ -25,7 +26,7 @@ - + diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/_Imports.cs similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/_Imports.cs From cce7b860be19bb5be16fc49cf5d85fbfcb032ff6 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 10 Nov 2022 12:10:00 +0800 Subject: [PATCH 30/38] chore: Modify code bad smell --- Masa.Framework.sln | 32 +++++------ Masa.Framework.sln.DotSettings | 4 +- .../Masa.BuildingBlocks.Exceptions.csproj | 2 +- .../MasaException.cs | 22 ++++---- .../MasaValidatorException.cs | 4 +- .../DefaultLanguageProvider.cs | 2 +- .../I18N.cs | 26 ++++----- .../{I18NOfT.cs => I18nOfT.cs} | 56 +++++++++---------- .../II18NOfT.cs | 2 +- .../Resources/MasaLanguageResource.cs | 2 +- .../ApplicationBuilderExtensions.cs | 3 +- .../Handlers/ExceptionHandlerMiddleware.cs | 6 +- .../Handlers/MvcGlobalExceptionFilter.cs | 4 +- .../Internal/LoggerExtensions.cs | 6 +- .../Masa.Contrib.Exceptions.csproj | 4 +- .../MasaExceptionContext.cs | 2 +- .../ApplicationBuilderExtensions.cs | 2 +- ...trib.Globalization.I18N.AspNetCore.csproj} | 2 +- .../README.md | 16 +++--- .../README.zh-CN.md | 20 +++---- .../_Imports.cs | 0 .../DccI18NResourceContributor.cs | 2 +- .../DccResource.cs | 2 +- .../Extensions/I18NOptionsExtensions.cs | 2 +- .../Extensions/I18NResourceExtensions.cs | 0 .../Internal/Constant.cs | 2 +- ...asa.Contrib.Globalization.I18N.Dcc.csproj} | 3 +- .../_Imports.cs | 2 +- .../Constant.cs | 21 +++++++ .../EmbeddedResourceUtils.cs | 10 ++-- .../Extensions/I18NResourceExtensions.cs | 6 +- .../Extensions/ServiceCollectionExtensions.cs | 18 +++--- .../FileConfigurationProvider.cs | 4 +- .../Internal/CultureUtils.cs | 43 ++++++++++++++ .../Internal/PathUtils.cs | 2 +- .../Json/JsonConfigurationProvider.cs | 2 +- .../JsonConfigurationProviderByEmbedded.cs | 9 +-- .../Json/JsonConfigurationSource.cs | 2 +- .../Json/JsonConfigurationSourceByEmbedded.cs | 2 +- .../LocalI18NResourceContributor.cs | 0 .../Masa.Contrib.Globalization.I18N.csproj} | 6 +- .../README.md | 10 ++-- .../README.zh-CN.md | 16 +++--- .../I18n/Framework/Languages/en-US.json | 0 .../I18n/Framework/Languages/zh-CN.json | 0 .../Framework/ParameterValidations/en-US.json | 0 .../Framework/ParameterValidations/zh-CN.json | 0 .../Resources/I18n/Framework/en-US.json | 0 .../Resources/I18n/Framework/zh-CN.json | 0 .../_Imports.cs | 10 ++-- .../Constant.cs | 25 --------- .../Internal/CultureUtils.cs | 52 ----------------- .../I18NTest.cs | 4 +- ...ntrib.Globalization.I18N.Dcc.Tests.csproj} | 9 ++- .../Resources/I18n/en-US.json | 0 .../Resources/I18n/supportedCultures.json | 0 .../Resources/I18n/zh-CN.json | 0 .../_Imports.cs | 0 .../I18nTest.cs} | 6 +- ...a.Contrib.Globalization.I18N.Tests.csproj} | 5 +- .../Resources/I18n/en-US.json | 0 .../Resources/I18n/supportedCultures.json | 0 .../Resources/I18n/zh-CN.json | 0 .../_Imports.cs | 0 .../StringTest.cs | 6 -- 65 files changed, 236 insertions(+), 262 deletions(-) rename src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/{I18NOfT.cs => I18nOfT.cs} (71%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.AspNetCore => Masa.Contrib.Globalization.I18N.AspNetCore}/Extensions/ApplicationBuilderExtensions.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj => Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj} (89%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.AspNetCore => Masa.Contrib.Globalization.I18N.AspNetCore}/README.md (83%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.AspNetCore => Masa.Contrib.Globalization.I18N.AspNetCore}/README.zh-CN.md (79%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.AspNetCore => Masa.Contrib.Globalization.I18N.AspNetCore}/_Imports.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/DccI18NResourceContributor.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/DccResource.cs (79%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/Extensions/I18NOptionsExtensions.cs (96%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/Extensions/I18NResourceExtensions.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/Internal/Constant.cs (81%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj => Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj} (70%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n.Dcc => Masa.Contrib.Globalization.I18N.Dcc}/_Imports.cs (90%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/EmbeddedResourceUtils.cs (76%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Extensions/I18NResourceExtensions.cs (95%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Extensions/ServiceCollectionExtensions.cs (92%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/FileConfigurationProvider.cs (95%) create mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Internal/PathUtils.cs (92%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Json/JsonConfigurationProvider.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Json/JsonConfigurationProviderByEmbedded.cs (90%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Json/JsonConfigurationSource.cs (95%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Json/JsonConfigurationSourceByEmbedded.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/LocalI18NResourceContributor.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj => Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj} (79%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/README.md (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/README.zh-CN.md (90%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/Languages/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/Languages/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/ParameterValidations/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/ParameterValidations/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/Resources/I18n/Framework/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18n => Masa.Contrib.Globalization.I18N}/_Imports.cs (61%) delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs delete mode 100644 src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Dcc.Tests => Masa.Contrib.Globalization.I18N.Dcc.Tests}/I18NTest.cs (93%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj => Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj} (83%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Dcc.Tests => Masa.Contrib.Globalization.I18N.Dcc.Tests}/Resources/I18n/en-US.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Dcc.Tests => Masa.Contrib.Globalization.I18N.Dcc.Tests}/Resources/I18n/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Dcc.Tests => Masa.Contrib.Globalization.I18N.Dcc.Tests}/Resources/I18n/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Dcc.Tests => Masa.Contrib.Globalization.I18N.Dcc.Tests}/_Imports.cs (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Tests/I18NTest.cs => Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs} (94%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj => Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj} (90%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Tests => Masa.Contrib.Globalization.I18N.Tests}/Resources/I18n/en-US.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Tests => Masa.Contrib.Globalization.I18N.Tests}/Resources/I18n/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Tests => Masa.Contrib.Globalization.I18N.Tests}/Resources/I18n/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18n.Tests => Masa.Contrib.Globalization.I18N.Tests}/_Imports.cs (100%) diff --git a/Masa.Framework.sln b/Masa.Framework.sln index b66626a33..4c00251d0 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -557,8 +557,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalizat EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Globalization", "Globalization", "{5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Globalization.I18n", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18n\Masa.BuildingBlocks.Globalization.I18n.csproj", "{AC84401A-58FD-4786-9E10-BA99D17ABB3E}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests", "src\Contrib\Service\Caller\Authentication\Tests\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests\Masa.Contrib.Service.Caller.Authentication.OpenIdConnect.Tests.csproj", "{BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}" @@ -599,15 +597,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.Da EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.DaprStarter.AspNetCore.Tests", "src\Contrib\Development\Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests.csproj", "{DD899DC4-A2B7-4C7B-A644-EDB56A61145C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n\Masa.Contrib.Globalization.I18n.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N\Masa.Contrib.Globalization.I18N.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D2E598D5-5E44-4275-AF03-4BAD07A0E13B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18n.Tests\Masa.Contrib.Globalization.I18n.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Tests\Masa.Contrib.Globalization.I18N.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n.Dcc\Masa.Contrib.Globalization.I18n.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Dcc\Masa.Contrib.Globalization.I18N.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18n.Dcc.Tests\Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exception", "Exception", "{84F366D3-6E9A-4101-AEC0-287CBA6984A8}" EndProject @@ -619,10 +617,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Exceptions", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Exceptions.Tests", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions.Tests\Masa.BuildingBlocks.Exceptions.Tests.csproj", "{921DCAAC-3146-4EDB-891C-D76089E4A451}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n.AspNetCore\Masa.Contrib.Globalization.I18n.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.AspNetCore\Masa.Contrib.Globalization.I18N.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Dispatcher.Events.FluentValidation", "src\Contrib\Dispatcher\Masa.Contrib.Dispatcher.Events.FluentValidation\Masa.Contrib.Dispatcher.Events.FluentValidation.csproj", "{66B1723A-D578-418C-B21C-2C3B5CBD1180}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.I18N", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18N\Masa.BuildingBlocks.Globalization.I18N.csproj", "{6088C3D3-E17E-41BC-A21F-F222F5123DF1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2023,14 +2023,6 @@ Global {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Release|Any CPU.Build.0 = Release|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Release|x64.ActiveCfg = Release|Any CPU {9BB5CC86-C2E8-4859-9610-50DB263605A3}.Release|x64.Build.0 = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.ActiveCfg = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Debug|x64.Build.0 = Debug|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|Any CPU.Build.0 = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.ActiveCfg = Release|Any CPU - {AC84401A-58FD-4786-9E10-BA99D17ABB3E}.Release|x64.Build.0 = Release|Any CPU {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}.Debug|Any CPU.Build.0 = Debug|Any CPU {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2199,6 +2191,14 @@ Global {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Release|Any CPU.Build.0 = Release|Any CPU {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Release|x64.ActiveCfg = Release|Any CPU {66B1723A-D578-418C-B21C-2C3B5CBD1180}.Release|x64.Build.0 = Release|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Debug|x64.ActiveCfg = Debug|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Debug|x64.Build.0 = Debug|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Release|Any CPU.Build.0 = Release|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Release|x64.ActiveCfg = Release|Any CPU + {6088C3D3-E17E-41BC-A21F-F222F5123DF1}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2473,7 +2473,6 @@ Global {9BB5CC86-C2E8-4859-9610-50DB263605A3} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} {D10FC534-0091-42B4-809F-82C1E2164ED5} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} = {950DA7D0-48C1-42BA-8E8F-F72C0DCE41C4} - {AC84401A-58FD-4786-9E10-BA99D17ABB3E} = {D10FC534-0091-42B4-809F-82C1E2164ED5} {8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A} = {FC4A0C94-47F7-4C9A-A7EC-138DE8EB842D} {BEA8E5A5-E7BD-4165-80CD-D1F53ED82D02} = {8D7D3D21-86DB-4FCC-8FF0-6E1587ABD22A} {03F476EF-022A-4370-B1C3-FEEDE3BB4E7F} = {41769FBF-91A8-48D1-B3BB-CAE4C814E7CD} @@ -2506,6 +2505,7 @@ Global {921DCAAC-3146-4EDB-891C-D76089E4A451} = {84F366D3-6E9A-4101-AEC0-287CBA6984A8} {B7AEC624-6A40-42E7-BDB5-4487ACE48CE4} = {5B129E6F-8CB7-4E2E-9F3E-C59CF22C9CA9} {66B1723A-D578-418C-B21C-2C3B5CBD1180} = {5BE84027-D1B4-4264-A7EC-E84658350CA7} + {6088C3D3-E17E-41BC-A21F-F222F5123DF1} = {D10FC534-0091-42B4-809F-82C1E2164ED5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/Masa.Framework.sln.DotSettings b/Masa.Framework.sln.DotSettings index ada53e2b1..1e0e7b13e 100644 --- a/Masa.Framework.sln.DotSettings +++ b/Masa.Framework.sln.DotSettings @@ -1,5 +1,5 @@  True True - True - True \ No newline at end of file + True + True \ No newline at end of file diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj index 63c029362..af9c871f2 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index d125c3b86..6abdfe711 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -13,7 +13,7 @@ public class MasaException : Exception public string? ErrorCode { get; private set; } /// - /// Provides error message that I18n is not used + /// Provides error message that I18N is not used /// public string? ErrorMessage { get; set; } @@ -32,25 +32,25 @@ internal II18N? I18N } } - private II18N? _frameworkI18N; + private II18N? _frameworkI18n; - internal II18N? FrameworkI18N + internal II18N? FrameworkI18n { get { TryInitialize(); - return _frameworkI18N; + return _frameworkI18n; } } - private bool _supportI18N; + private bool _supportI18n; - internal bool SupportI18N + internal bool SupportI18n { get { TryInitialize(); - return _supportI18N; + return _supportI18n; } } @@ -64,9 +64,9 @@ private void TryInitialize() private void Initialize() { - _frameworkI18N = MasaApp.GetService>(); + _frameworkI18n = MasaApp.GetService>(); _i18N = MasaApp.GetService>(); - _supportI18N = _frameworkI18N != null; + _supportI18n = _frameworkI18n != null; _initialize = true; } @@ -111,7 +111,7 @@ public string GetLocalizedMessage() protected virtual string GetLocalizedMessageExecuting() { - if (!SupportI18N) + if (!SupportI18n) { if (string.IsNullOrWhiteSpace(ErrorMessage)) return Message; @@ -122,7 +122,7 @@ protected virtual string GetLocalizedMessageExecuting() if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) { //The current framework frame exception - return FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; + return FrameworkI18n!.T(ErrorCode!, false, GetParameters()) ?? Message; } return I18N!.T(ErrorCode, false, GetParameters()) ?? Message; diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs index a8fb1c025..a2716c2de 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs @@ -192,7 +192,7 @@ private static void Throw( protected override string GetLocalizedMessageExecuting() { string message; - if (!SupportI18N) + if (!SupportI18n) { message = string.IsNullOrWhiteSpace(ErrorMessage) ? Message : string.Format(ErrorMessage, GetParameters()); } @@ -200,7 +200,7 @@ protected override string GetLocalizedMessageExecuting() else if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) { //The current framework frame exception - message = FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; + message = FrameworkI18n!.T(ErrorCode!, false, GetParameters()) ?? Message; } else { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs index f3991ff8a..941efa794 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs @@ -8,7 +8,7 @@ public class DefaultLanguageProvider : ILanguageProvider private readonly II18N _i18N; private readonly IOptions _options; - private static Dictionary _languages = new() + private static readonly Dictionary _languages = new() { { "en-US", "English (United States)" }, { "zh-CN", "中文 (简体)" } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs index 8365db955..efb2a16f1 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs @@ -3,13 +3,13 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public static class I18n +public static class I18N { private static readonly IServiceProvider _serviceProvider = MasaApp.RootServiceProvider; - private static readonly II18N _i18N = InitI18N(); + private static readonly II18N Ii18N = InitI18n(); private static readonly ILanguageProvider _languageProvider = InitLanguage(); - static II18N InitI18N() => _serviceProvider.GetRequiredService(); + static II18N InitI18n() => _serviceProvider.GetRequiredService(); static ILanguageProvider InitLanguage() => _serviceProvider.GetRequiredService(); @@ -18,7 +18,7 @@ public static class I18n /// /// The name of the string resource. /// - public static string T(string name) => _i18N.T(name); + public static string T(string name) => Ii18N.T(name); /// /// Gets the string resource with the given name. @@ -26,14 +26,14 @@ public static class I18n /// The name of the string resource. /// Return Key when key does not exist, default: true /// - public static string? T(string name, bool returnKey) => _i18N.T(name, returnKey); + public static string? T(string name, bool returnKey) => Ii18N.T(name, returnKey); /// /// Gets the string resource with the given name and formatted with the supplied arguments. /// /// The name of the string resource. /// The values to format the string with. - public static string T(string name, params object[] arguments) => _i18N.T(name, arguments); + public static string T(string name, params object[] arguments) => Ii18N.T(name, arguments); /// /// Gets the string resource with the given name and formatted with the supplied arguments. @@ -41,9 +41,9 @@ public static class I18n /// The name of the string resource. /// Return Key when key does not exist, default: true /// The values to format the string with. - public static string? T(string name, bool returnKey, params object[] arguments) => _i18N.T(name, returnKey, arguments); + public static string? T(string name, bool returnKey, params object[] arguments) => Ii18N.T(name, returnKey, arguments); - public static CultureInfo GetCultureInfo() => _i18N.GetCultureInfo(); + public static CultureInfo GetCultureInfo() => Ii18N.GetCultureInfo(); /// /// Set the CultureName @@ -51,20 +51,20 @@ public static class I18n /// /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). - public static void SetCulture(string cultureName, bool useUserOverride = true) => _i18N.SetCulture(cultureName, useUserOverride); + public static void SetCulture(string cultureName, bool useUserOverride = true) => Ii18N.SetCulture(cultureName, useUserOverride); /// /// Set the CultureName /// Data used to define "regional options", standards, formats, etc /// /// - public static void SetCulture(CultureInfo culture) => _i18N.SetCulture(culture); + public static void SetCulture(CultureInfo culture) => Ii18N.SetCulture(culture); /// /// get interface language /// /// - public static CultureInfo GetUiCultureInfo() => _i18N.GetUiCultureInfo(); + public static CultureInfo GetUiCultureInfo() => Ii18N.GetUiCultureInfo(); /// /// Set the CultureName for the current request @@ -72,14 +72,14 @@ public static class I18n /// /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). - public static void SetUiCulture(string cultureName, bool useUserOverride = true) => _i18N.SetUiCulture(cultureName, useUserOverride); + public static void SetUiCulture(string cultureName, bool useUserOverride = true) => Ii18N.SetUiCulture(cultureName, useUserOverride); /// /// Set the CultureName for the current request /// Used to set the interface language /// /// - public static void SetUiCulture(CultureInfo culture) => _i18N.SetUiCulture(culture); + public static void SetUiCulture(CultureInfo culture) => Ii18N.SetUiCulture(culture); public static IReadOnlyList GetLanguages() => _languageProvider.GetLanguages(); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs similarity index 71% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NOfT.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs index 747bdb076..92a3e4ff9 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs @@ -3,7 +3,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public class I18nOfT : II18N +public class I18N : II18N where TResourceSource : class { private readonly I18NResource? _resource; private readonly List _baseResources; @@ -16,7 +16,7 @@ public class I18nOfT : II18N public string? this[string name, bool returnKey, params object[] arguments] => T(name, returnKey, arguments); - public I18nOfT() + public I18N() { _resource = I18NResourceResourceConfiguration.Resources.GetOrNull(); @@ -25,8 +25,7 @@ public I18nOfT() .ToList() ?? new List(); } - public virtual string T(string name) - => T(name, true)!; + public string T(string name) => T(name, true)!; /// /// Gets the string resource with the given name. @@ -34,8 +33,22 @@ public virtual string T(string name) /// The name of the string resource. /// Return Key when key does not exist, default: true /// - public virtual string? T(string name, bool returnKey) - => Core(name, returnKey, out _); + public string? T(string name, bool returnKey) => Core(name, returnKey, out _); + + public string T(string name, params object[] arguments) + => T(name, true, arguments)!; + + public string? T(string name, bool returnKey, params object[] arguments) + { + ArgumentNullException.ThrowIfNull(name); + + var value = Core(name, returnKey, out bool isExist); + + if (isExist) + return string.Format(GetCultureInfo(), value!, arguments); + + return returnKey ? name : null; + } /// /// Gets the string resource with the given name. @@ -62,9 +75,9 @@ public virtual string T(string name) return value; } - public virtual string? GetOrNull(string name) => GetOrNull(_resource, name); + public string? GetOrNull(string name) => GetOrNull(_resource, name); - public virtual string? GetOrNull(I18NResource? i18NResource, string name) + public string? GetOrNull(I18NResource? i18NResource, string name) { if (i18NResource == null) return null; @@ -73,32 +86,17 @@ public virtual string T(string name) return resourceContributor?.GetOrNull(name); } - public virtual string T(string name, params object[] arguments) - => T(name, true, arguments)!; - - public virtual string? T(string name, bool returnKey, params object[] arguments) - { - ArgumentNullException.ThrowIfNull(name); - - var value = Core(name, returnKey, out bool isExist); - - if (isExist) - return string.Format(GetCultureInfo(), value!, arguments); - - return returnKey ? name : null; - } - - public virtual CultureInfo GetCultureInfo() => CultureInfo.CurrentCulture; + public CultureInfo GetCultureInfo() => CultureInfo.CurrentCulture; - public virtual void SetCulture(string cultureName, bool useUserOverride = true) + public void SetCulture(string cultureName, bool useUserOverride = true) => SetCulture(new CultureInfo(cultureName, useUserOverride)); - public virtual void SetCulture(CultureInfo culture) => CultureInfo.CurrentCulture = culture; + public void SetCulture(CultureInfo culture) => CultureInfo.CurrentCulture = culture; - public virtual CultureInfo GetUiCultureInfo() => CultureInfo.CurrentUICulture; + public CultureInfo GetUiCultureInfo() => CultureInfo.CurrentUICulture; - public virtual void SetUiCulture(string cultureName, bool useUserOverride = true) + public void SetUiCulture(string cultureName, bool useUserOverride = true) => SetUiCulture(new CultureInfo(cultureName, useUserOverride)); - public virtual void SetUiCulture(CultureInfo culture) => CultureInfo.CurrentUICulture = culture; + public void SetUiCulture(CultureInfo culture) => CultureInfo.CurrentUICulture = culture; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs index 0a32bf50c..294071619 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs @@ -3,7 +3,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public interface II18N : II18N +public interface II18N : II18N where TResourceSource : class { } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs index c8da63476..67006b40b 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs @@ -7,5 +7,5 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public class MasaLanguageResource { - + } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index 26e7460cb..637ace2f0 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -13,7 +13,6 @@ public static class ApplicationBuilderExtensions /// /// /// - /// Whether to enable i18n /// public static IApplicationBuilder UseMasaExceptionHandler( this IApplicationBuilder app, @@ -22,7 +21,7 @@ public static IApplicationBuilder UseMasaExceptionHandler( var option = new MasaExceptionHandlerOptions(); exceptionHandlingOptions?.Invoke(option); - app.UseI18N(); + app.UseI18n(); app.UseMiddleware(Options.Create(option)); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index 2ba24e8f2..ce7a6e156 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -27,7 +27,7 @@ public ExceptionHandlerMiddleware( public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceProvider) { - var frameworkI18N = serviceProvider.GetService>(); + var frameworkI18n = serviceProvider.GetService>(); try { await _next(httpContext); @@ -67,8 +67,8 @@ await httpContext.Response.WriteTextAsync( } else if (_options.CatchAllException) { - string message = frameworkI18N == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : - frameworkI18N[ErrorCode.INTERNAL_SERVER_ERROR]; + string message = frameworkI18n == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : + frameworkI18n[ErrorCode.INTERNAL_SERVER_ERROR]; await httpContext.Response.WriteTextAsync(httpStatusCode, message); } else diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs index f2f4a3ae4..2982136cd 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs @@ -15,13 +15,13 @@ public class MvcGlobalExceptionFilter : IExceptionFilter private readonly IMasaExceptionHandler? _masaExceptionHandler; private readonly MasaExceptionHandlerOptions _options; private readonly MasaExceptionLogRelationOptions _logRelationOptions; - private readonly I18nOfT? _frameworkI18N; + private readonly I18N? _frameworkI18N; private readonly ILogger? _logger; public MvcGlobalExceptionFilter(IServiceProvider serviceProvider, IOptions options, IOptions logRelationOptions, - I18nOfT? frameworkI18N = null, + I18N? frameworkI18N = null, ILogger? logger = null) { _serviceProvider = serviceProvider; diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs index 0a1bc8546..9e8e50ed0 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Internal/LoggerExtensions.cs @@ -19,13 +19,13 @@ public static void WriteLog( { if (masaException.LogLevel != null) { - logger.Log(masaException.LogLevel!.Value, exception, message); + logger.Log(masaException.LogLevel!.Value, exception, "{Message}", message); return; } - if(masaException is UserFriendlyException) + if (masaException is UserFriendlyException) defaultLogLevel = LogLevel.Information; } var logLevel = logRelationOptions.GetLogLevel(exception, defaultLogLevel); - logger.Log(logLevel, exception, message); + logger.Log(logLevel, exception, "{Message}", message); } } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj index bb1f4fc8c..0d5372eb1 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs index 22f4cba33..08e9a7eec 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs @@ -22,7 +22,7 @@ public class MasaExceptionContext public int StatusCode { get; set; } /// - /// Error code to provide support for subsequent I18n + /// Error code to provide support for subsequent I18N /// public string? ErrorCode { get; set; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index 9f47b6a1f..dfac8bc07 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -10,7 +10,7 @@ public static class ApplicationBuilderExtensions { private static bool _isInitialize; - public static IApplicationBuilder UseI18N(this IApplicationBuilder app) + public static IApplicationBuilder UseI18n(this IApplicationBuilder app) { if (_isInitialize) return app; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj similarity index 89% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj index ef26fdad6..3da5d7f8d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md similarity index 83% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md index 856b545a3..6e27b173b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md @@ -1,17 +1,17 @@ [中](README.zh-CN.md) | EN -Provides the ability to parse and obtain Culture, and use it with [I18N](../Masa.Contrib.Globalization.I18n/README.md). Currently, there are three ways to switch languages: +Provides the ability to parse and obtain Culture, and use it with [I18N](../Masa.Contrib.Globalization.I18N/README.md). Currently, there are three ways to switch languages: * URL parameter method: ?culture=en-US, this method has the highest priority, the format is: culture=region code * Cookies method: call L.SetCulture (region code) method to switch * Client browser language automatic matching: If neither of the previous two methods are set, it supports automatic matching according to the client browser language. -## Masa.Contrib.Globalization.I18n.AspNetCore +## Masa.Contrib.Globalization.I18N.AspNetCore Example: ``` powershell -Install-Package Masa.Contrib.Globalization.I18n.AspNetCore +Install-Package Masa.Contrib.Globalization.I18N.AspNetCore ``` ### getting Started @@ -20,7 +20,7 @@ Install-Package Masa.Contrib.Globalization.I18n.AspNetCore ``` structure - Resources - - I18n + - I18N - en-US.json - zh-CN.json - supportedCultures.json @@ -76,18 +76,18 @@ Install-Package Masa.Contrib.Globalization.I18n.AspNetCore 2. Register to use I18N, modify `Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` -3. Use `Masa.Contrib.Globalization.I18n.AspNetCore` to provide the ability to parse Culture +3. Use `Masa.Contrib.Globalization.I18N.AspNetCore` to provide the ability to parse Culture ``` C# -app.UseI18N(); +app.UseI18n(); ``` 4. How to use I18N -* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) +* Get `II18n` from DI (**II18n** is the interface, supports getting from DI) * Use `I18N` (**I18N** is a static class) Take `I18N` as an example: diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md similarity index 79% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md index 9ba770682..bf90e5b85 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md @@ -1,17 +1,17 @@ 中 | [EN](README.md) -提供解析获取Culture的能力,配合[I18N](../Masa.Contrib.Globalization.I18n/README.zh-CN.md)来使用,目前支持三种方式进行切换语言: +提供解析获取Culture的能力,配合[I18N](../Masa.Contrib.Globalization.I18N/README.zh-CN.md)来使用,目前支持三种方式进行切换语言: * URL 参数 方式: ?culture=en-US,此方式优先级最高,格式为:culture=区域码 * Cookies 方式:调用 L.SetCulture(区域码) 方式切换 * 客户端浏览器语言自动匹配:如果前面两种方式都没有设置,支持自动根据客户端浏览器语言进行匹配。 -## Masa.Contrib.Globalization.I18n.AspNetCore +## Masa.Contrib.Globalization.I18N.AspNetCore 用例: ``` powershell -Install-Package Masa.Contrib.Globalization.I18n.AspNetCore +Install-Package Masa.Contrib.Globalization.I18N.AspNetCore ``` ### 入门 @@ -20,7 +20,7 @@ Install-Package Masa.Contrib.Globalization.I18n.AspNetCore ``` structure - Resources - - I18n + - I18N - en-US.json - zh-CN.json - supportedCultures.json @@ -73,21 +73,21 @@ Install-Package Masa.Contrib.Globalization.I18n.AspNetCore ] ``` -2. 注册使用I18N, 修改`Program.cs` +2. 注册使用I18n, 修改`Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` -3. 使用`Masa.Contrib.Globalization.I18n.AspNetCore`提供解析Culture的能力 +3. 使用`Masa.Contrib.Globalization.I18N.AspNetCore`提供解析Culture的能力 ``` C# -app.UseI18N(); +app.UseI18n(); ``` -4. 如何使用I18N +4. 如何使用I18n -* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) +* 从DI获取`II18n` (**II18n**是接口,支持从DI获取) * 使用`I18N` (**I18N**是静态类) 以`I18N`为例: diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18NResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs index b6063df0e..9ace601d0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18NResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Dcc; +namespace Masa.Contrib.Globalization.I18N.Dcc; public class DccI18NResourceContributor : II18NResourceContributor { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs similarity index 79% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs index 032c37d79..63d098a0a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Dcc; +namespace Masa.Contrib.Globalization.I18N.Dcc; public class DccResource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs similarity index 96% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NOptionsExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs index d58f2b33e..a0c44c66c 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18n; +namespace Masa.Contrib.Globalization.I18N; public static class I18NOptionsExtensions { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18NResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs similarity index 81% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs index 375837e3e..15f510c3b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Dcc.Internal; +namespace Masa.Contrib.Globalization.I18N.Dcc.Internal; internal static class Constant { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj similarity index 70% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj index 900830af2..e4d4212da 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj @@ -7,9 +7,8 @@ - - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs similarity index 90% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs index f67ae25c4..6bf9df3d0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs @@ -5,7 +5,7 @@ global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Globalization.I18N; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; -global using Masa.Contrib.Globalization.I18n.Dcc; +global using Masa.Contrib.Globalization.I18N.Dcc; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using System.Diagnostics.CodeAnalysis; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs new file mode 100644 index 000000000..f985ac6aa --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs @@ -0,0 +1,21 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N; + +public static class Constant +{ + public const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; + + public static readonly string DefaultResourcePath + = Path.Combine("Resources", "I18N"); + + internal static readonly string DefaultFrameworkResourcePath + = Path.Combine(DefaultResourcePath, "Framework"); + + internal static readonly string DefaultFrameworkParameterValidationResourcePath = + Path.Combine(DefaultFrameworkResourcePath, "ParameterValidations"); + + internal static readonly string DefaultFrameworkLanguageResourcePath + = Path.Combine(DefaultFrameworkResourcePath, "Languages"); +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs similarity index 76% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs index f3cec8f26..b9749378f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n; +namespace Masa.Contrib.Globalization.I18N; public class EmbeddedResourceUtils { @@ -24,7 +24,7 @@ public List> GetResources(string resourcesDirec foreach (var item in _list) { var data = item.Value.Where(resourceName - => resourceName.IndexOf(FormatResourcesDirectory(resourcesDirectory), StringComparison.OrdinalIgnoreCase) > 0).ToArray(); + => resourceName.Contains(FormatResourcesDirectory(resourcesDirectory), StringComparison.OrdinalIgnoreCase)).ToArray(); if (data.Length > 0) { list.Add(new KeyValuePair(item.Key, data)); @@ -33,9 +33,9 @@ public List> GetResources(string resourcesDirec return list; } - public Stream? GetStream(Assembly assembly, string fileName) => assembly.GetManifestResourceStream(fileName); + public static Stream? GetStream(Assembly assembly, string fileName) => assembly.GetManifestResourceStream(fileName); - public string? GetCulture(string resourcesDirectory, string fileName) + public static string? GetCulture(string resourcesDirectory, string fileName) { var formatResourcesDirectory = FormatResourcesDirectory(resourcesDirectory); var index = fileName.IndexOf(formatResourcesDirectory, StringComparison.OrdinalIgnoreCase); @@ -45,7 +45,7 @@ public List> GetResources(string resourcesDirec return null; } - private string FormatResourcesDirectory(string resourcesDirectory) + private static string FormatResourcesDirectory(string resourcesDirectory) { return resourcesDirectory.Replace(Path.DirectorySeparatorChar.ToString(), "."); } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18NResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs index 32e701536..72400b451 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs @@ -87,7 +87,7 @@ private static IConfiguration AddJsonConfigurationSource( configuration, () => new List() { - new JsonConfigurationSource(resourceType, resourcesDirectory, supportedCultures.Select(c => c.Culture), + new MasaJsonConfigurationSource(resourceType, resourcesDirectory, supportedCultures.Select(c => c.Culture), useMasaConfiguration) }); } @@ -112,10 +112,10 @@ private static IConfiguration AddJsonConfigurationSourceByEmbeddedResource( { foreach (var fileName in item.Value) { - var stream = embeddedResourceUtils.GetStream(item.Key, fileName); + var stream = EmbeddedResourceUtils.GetStream(item.Key, fileName); if (stream == null) continue; - var culture = embeddedResourceUtils.GetCulture(resourcesDirectory, fileName); + var culture = EmbeddedResourceUtils.GetCulture(resourcesDirectory, fileName); if (culture != null && supportedCultures.Any(cul => cul.Culture.Equals(culture, StringComparison.OrdinalIgnoreCase))) list.Add(new JsonConfigurationSourceByEmbedded(resourceType, stream, culture, useMasaConfiguration)); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs similarity index 92% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index af3e8b463..b813f5c87 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -31,7 +31,7 @@ public static IServiceCollection AddI18NByEmbedded( settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18nConstant.SUPPORTED_CULTURES_NAME : supportCultureName; }, action); } @@ -59,7 +59,7 @@ public static IServiceCollection TestAddI18N( return services.TestAddI18N(settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18nConstant.SUPPORTED_CULTURES_NAME : supportCultureName; settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); @@ -88,21 +88,21 @@ private static IServiceCollection AddI18NByFramework(this IServiceCollection ser options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18NConstant.DefaultFrameworkResourcePath, + resource.AddJson(ContribI18nConstant.DefaultFrameworkResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18NConstant.DefaultFrameworkParameterValidationResourcePath, + resource.AddJson(ContribI18nConstant.DefaultFrameworkParameterValidationResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18NConstant.DefaultFrameworkLanguageResourcePath, + resource.AddJson(ContribI18nConstant.DefaultFrameworkLanguageResourcePath, languageSettings.SupportedCultures); }); }); @@ -118,10 +118,10 @@ private static CultureSettings AddAndGetCultureSettings( settingsAction?.Invoke(settings); if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) - settings.ResourcesDirectory = ContribI18NConstant.DefaultResourcePath; + settings.ResourcesDirectory = ContribI18nConstant.DefaultResourcePath; if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) - settings.SupportCultureName = ContribI18NConstant.SUPPORTED_CULTURES_NAME; + settings.SupportCultureName = ContribI18nConstant.SUPPORTED_CULTURES_NAME; if (!settings.SupportedCultures.Any()) settings.SupportedCultures = @@ -141,7 +141,7 @@ private static IServiceCollection AddI18NCore( CultureSettings cultureSettings) where TResource : class { services.AddOptions(); - services.TryAddTransient(typeof(II18N<>), typeof(I18nOfT<>)); + services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); services.TryAddSingleton(); services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); @@ -151,7 +151,7 @@ private static IServiceCollection AddI18NCore( options.Resources.TryAdd(resource => { if (assemblies.Any()) resource.Assemblies = assemblies; - resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, + resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18nConstant.DefaultResourcePath, localLanguageSettings.SupportedCultures); }); }); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs index f1c55a8c0..b16d851a8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n; +namespace Masa.Contrib.Globalization.I18N; public abstract class FileConfigurationProvider : ConfigurationProvider { @@ -11,7 +11,7 @@ public abstract class FileConfigurationProvider : ConfigurationProvider private readonly bool _useMasaConfiguration; private readonly Dictionary> _dictionary; - protected FileConfigurationProvider(JsonConfigurationSource configurationSource) + protected FileConfigurationProvider(MasaJsonConfigurationSource configurationSource) { _resourceTypeName = configurationSource.ResourceType.Name; _languageDirectory = configurationSource.LanguageDirectory; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs new file mode 100644 index 000000000..cce4a0b48 --- /dev/null +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs @@ -0,0 +1,43 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Globalization.I18N.Internal; + +internal static class CultureUtils +{ + public static List GetSupportedCultures( + string languageDirectory, + string supportCultureName) + { + int retry = 0; + int maxRetry = 10; + while (retry < maxRetry) + { + try + { + var supportCultureFilePath = Path.Combine(languageDirectory, supportCultureName); + var content = File.ReadAllText(supportCultureFilePath); + return System.Text.Json.JsonSerializer.Deserialize>(content)!; + } + catch (FileNotFoundException) + { + return new List() + { + new("en-us", "English") + }; + } + catch (IOException) + { + if (retry == maxRetry - 1) throw; + } + finally + { + retry++; + } + } + return new List() + { + new("en-us", "English") + }; + } +} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs similarity index 92% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs index 43d62d7e2..a1f299af1 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18n; +namespace Masa.Contrib.Globalization.I18N; internal static class PathUtils { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs index 77c3a5879..b93501aaa 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Json; +namespace Masa.Contrib.Globalization.I18N.Json; public class JsonConfigurationProvider : FileConfigurationProvider { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs similarity index 90% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs index dae33b74a..1c77b93f6 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs @@ -1,16 +1,13 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -using Microsoft.Extensions.Configuration.Json; - -namespace Masa.Contrib.Globalization.I18n.Json; +namespace Masa.Contrib.Globalization.I18N.Json; public class JsonConfigurationProviderByEmbedded : ConfigurationProvider { private readonly string _resourceTypeName; private readonly Stream _stream; private readonly bool _useMasaConfiguration; - private readonly string _culture; private Dictionary _dictionary; private readonly ConfigurationBuilder _configurationBuilder; private readonly string _prefix; @@ -20,10 +17,10 @@ public JsonConfigurationProviderByEmbedded(JsonConfigurationSourceByEmbedded sou _resourceTypeName = sourceByEmbedded.ResourceType.Name; _stream = sourceByEmbedded.Stream; _useMasaConfiguration = sourceByEmbedded.UseMasaConfiguration; - _culture = sourceByEmbedded.Culture; + var culture = sourceByEmbedded.Culture; _dictionary = new(StringComparer.OrdinalIgnoreCase); _configurationBuilder = new ConfigurationBuilder(); - _prefix = FormatKey(_culture); + _prefix = FormatKey(culture); } public override void Load() diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs index 98430e83e..2a941b8c0 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Json; +namespace Masa.Contrib.Globalization.I18N.Json; public class JsonConfigurationSource : IConfigurationSource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs index 074e1277b..591189cbe 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Json; +namespace Masa.Contrib.Globalization.I18N.Json; public class JsonConfigurationSourceByEmbedded : IConfigurationSource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/LocalI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/LocalI18NResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj similarity index 79% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj index 8bf37049e..1d37d8bbe 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj @@ -8,7 +8,7 @@ - + @@ -18,8 +18,8 @@ - - + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md index 39232c3ce..c3fc4663a 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md @@ -2,12 +2,12 @@ Provide [Internationalization](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization) capability -## Masa.Contrib.Globalization.I18n +## Masa.Contrib.Globalization.I18N Example: ``` powershell -Install-Package Masa.Contrib.Globalization.I18n +Install-Package Masa.Contrib.Globalization.I18N ``` ### getting Started @@ -16,7 +16,7 @@ Install-Package Masa.Contrib.Globalization.I18n ``` structure - Resources - - I18n + - I18N - en-US.json - zh-CN.json - supportedCultures.json @@ -72,12 +72,12 @@ Install-Package Masa.Contrib.Globalization.I18n 2. Register to use I18N, modify `Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` 3. How to use I18N -* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) +* Get `II18n` from DI (**II18n** is the interface, supports getting from DI) * Use `I18N` (**I18N** is a static class) Take `I18N` as an example: diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md similarity index 90% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md index 1b8238ab5..d200f241e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md @@ -2,12 +2,12 @@ 提供[国际化](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization)能力 -## Masa.Contrib.Globalization.I18n +## Masa.Contrib.Globalization.I18N 用例: ``` powershell -Install-Package Masa.Contrib.Globalization.I18n +Install-Package Masa.Contrib.Globalization.I18N ``` ### 入门 @@ -16,7 +16,7 @@ Install-Package Masa.Contrib.Globalization.I18n ``` structure - Resources - - I18n + - I18N - en-US.json - zh-CN.json - supportedCultures.json @@ -69,15 +69,15 @@ Install-Package Masa.Contrib.Globalization.I18n ] ``` -2. 注册使用I18N, 修改`Program.cs` +2. 注册使用I18n, 修改`Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` -3. 如何使用I18N +3. 如何使用I18n -* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) +* 从DI获取`II18n` (**II18n**是接口,支持从DI获取) * 使用`I18N` (**I18N**是静态类) 以`I18N`为例: @@ -87,7 +87,7 @@ var home = I18N.T("Home"); //获取键值Home对应语言的值,此方法调 var name = I18N.T("User.Name");//输出:名称(支持嵌套) ``` -### I18N提供 +### I18n提供 * SetCulture (string cultureName): 将CurrentCulture切换成zh-CN,它更改后数字、日期等表示格式也随之改变 * SetUiCulture (string cultureName): 将界面语言(CurrentUICulture)切换成zh-CN diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs similarity index 61% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index 4de763b05..67e25bb54 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -4,14 +4,16 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Globalization.I18N; -global using Masa.Contrib.Globalization.I18n; -global using Masa.Contrib.Globalization.I18n.Internal; -global using Masa.Contrib.Globalization.I18n.Json; +global using Masa.Contrib.Globalization.I18N; +global using Masa.Contrib.Globalization.I18N.Internal; +global using Masa.Contrib.Globalization.I18N.Json; global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.Configuration.Json; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.Extensions.Localization; global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; global using System.Reflection; -global using ContribI18NConstant = Masa.Contrib.Globalization.I18n.Constant; +global using ContribI18nConstant = Masa.Contrib.Globalization.I18N.Constant; +global using MasaJsonConfigurationSource = Masa.Contrib.Globalization.I18N.Json.JsonConfigurationSource; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs deleted file mode 100644 index 00981fb67..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18n; - -public static class Constant -{ - public const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; - - public static readonly string DefaultResourcePath; - - internal static readonly string DefaultFrameworkResourcePath; - - internal static readonly string DefaultFrameworkParameterValidationResourcePath; - - internal static readonly string DefaultFrameworkLanguageResourcePath; - - static Constant() - { - DefaultResourcePath = Path.Combine("Resources", "I18n"); - DefaultFrameworkResourcePath = Path.Combine(DefaultResourcePath, "Framework"); - DefaultFrameworkParameterValidationResourcePath = Path.Combine(DefaultFrameworkResourcePath, "ParameterValidations"); - DefaultFrameworkLanguageResourcePath = Path.Combine(DefaultFrameworkResourcePath, "Languages"); - } -} diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs deleted file mode 100644 index a689691e7..000000000 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Globalization.I18n.Internal; - -internal static class CultureUtils -{ - public static List GetSupportedCultures( - string languageDirectory, - string supportCultureName) - { - int retry = 0; - start: - try - { - var fileName = Path.Combine(languageDirectory, supportCultureName); - using var fileStream = new FileStream(fileName, FileMode.Open); - if (!fileStream.CanRead) - { - retry++; - if (retry <= 10) - { - Task.Delay(300); - goto start; - } - throw new FileLoadException("Failed to get supported languages", fileName); - } - } - catch (FileNotFoundException ex) - { - // //todo: Write a log, prompting to use English by default - return new List() - { - new("en-us", "English") - }; - } - catch (IOException ex) - { - retry++; - if (retry <= 10) - { - Task.Delay(300); - goto start; - } - throw; - } - - var supportCultureFilePath = Path.Combine(languageDirectory, supportCultureName); - var content = File.ReadAllText(supportCultureFilePath); - return System.Text.Json.JsonSerializer.Deserialize>(content)!; - } -} diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs similarity index 93% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18NTest.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs index a64a2d731..599dfd4ef 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs @@ -1,12 +1,12 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Dcc.Tests; +namespace Masa.Contrib.Globalization.I18N.Dcc.Tests; [TestClass] public class I18NTest { - private const string DEFAULT_RESOURCE = "Resources/I18n"; + private const string DEFAULT_RESOURCE = "Resources/I18N"; [TestInitialize] public void Initialize() diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj similarity index 83% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj index 85a75ce83..ef4a89bde 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj @@ -5,7 +5,6 @@ enable false enable - Masa.Contrib.Globalization.I18n.Dcc.Tests @@ -24,17 +23,17 @@ - + - + Always - + Always - + Always diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/_Imports.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs similarity index 94% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18NTest.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs index 501bdaff7..e494df7bd 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs @@ -1,12 +1,12 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18n.Tests; +namespace Masa.Contrib.Globalization.I18N.Tests; [TestClass] -public class I18NTest +public class I18nTest { - private const string DEFAULT_RESOURCE = "Resources/I18n"; + private const string DEFAULT_RESOURCE = "Resources/I18N"; [TestInitialize] public void Initialize() diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj similarity index 90% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj index 7c7c64021..793a8e58d 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj @@ -5,7 +5,6 @@ enable false enable - Masa.Contrib.Globalization.I18n.Tests @@ -26,11 +25,11 @@ - + - + Always diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/_Imports.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs diff --git a/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs b/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs index 63842d040..9a9220ef3 100644 --- a/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs +++ b/src/Utils/Extensions/Tests/Masa.Utils.Extensions.DotNet.Tests/StringTest.cs @@ -21,10 +21,4 @@ public void TestTrimEnd(string value, string trimParameter, string result) { Assert.AreEqual(result, value.TrimEnd(trimParameter, StringComparison.OrdinalIgnoreCase)); } - - [TestMethod] - public void Test() - { - - } } From 7bc010e3b721f4d93e7ae61e5ab2eb776004380d Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 10 Nov 2022 14:36:45 +0800 Subject: [PATCH 31/38] chore: Modify code bad smell --- .../Constant.cs | 0 .../CultureModel.cs | 0 .../CultureSettings.cs | 0 .../DefaultLanguageProvider.cs | 0 .../I18N.cs | 0 .../I18NResource.cs | 0 .../I18NResourceDictionary.cs | 0 .../I18NResourceResourceConfiguration.cs | 0 .../I18nOfT.cs | 0 .../II18N.cs | 0 .../II18NOfT.cs | 0 .../II18NResourceContributor.cs | 0 .../ILanguageProvider.cs | 0 .../InheritResourceAttribute.cs | 0 .../LanguageInfo.cs | 0 .../Masa.BuildingBlocks.Globalization.I18N.csproj} | 1 - .../Options/I18NOptions.cs | 0 .../Options/MasaI18NOptions.cs | 0 .../Resources/DefaultResource.cs | 0 .../Resources/MasaFrameworkResource.cs | 0 .../Resources/MasaLanguageResource.cs | 0 .../Resources/MasaParameterValidationResource.cs | 0 .../_Imports.cs | 0 23 files changed, 1 deletion(-) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/Constant.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/CultureModel.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/CultureSettings.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/DefaultLanguageProvider.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/I18N.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/I18NResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/I18NResourceDictionary.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/I18NResourceResourceConfiguration.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/I18nOfT.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/II18N.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/II18NOfT.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/II18NResourceContributor.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/ILanguageProvider.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/InheritResourceAttribute.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/LanguageInfo.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj => Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj} (82%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/Options/I18NOptions.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/Options/MasaI18NOptions.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/Resources/DefaultResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/Resources/MasaFrameworkResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/Resources/MasaLanguageResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/Resources/MasaParameterValidationResource.cs (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18n => Masa.BuildingBlocks.Globalization.I18N}/_Imports.cs (100%) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Constant.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Constant.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureModel.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureModel.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureSettings.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureSettings.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18N.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceDictionary.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceResourceConfiguration.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18NResourceResourceConfiguration.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18N.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NOfT.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18NResourceContributor.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/ILanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/ILanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/InheritResourceAttribute.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/InheritResourceAttribute.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/LanguageInfo.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj similarity index 82% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj index 198661ec9..b3d41f5ba 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj @@ -4,7 +4,6 @@ net6.0 enable enable - Masa.BuildingBlocks.Globalization.I18N diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/I18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/I18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/DefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/DefaultResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaFrameworkResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaFrameworkResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaParameterValidationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaParameterValidationResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/_Imports.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs From aa49bef5858d32304f2e4367b2f84e776dbc2346 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 10 Nov 2022 15:04:14 +0800 Subject: [PATCH 32/38] chore: deal with bad taste --- .../MasaException.cs | 20 +++++++++---------- .../MasaValidatorException.cs | 4 ++-- .../I18N.cs | 4 ++-- .../ApplicationBuilderExtensions.cs | 2 +- .../Handlers/ExceptionHandlerMiddleware.cs | 6 +++--- .../ApplicationBuilderExtensions.cs | 2 +- .../README.md | 6 +++--- .../README.zh-CN.md | 10 +++++----- .../Extensions/ServiceCollectionExtensions.cs | 16 +++++++-------- .../Masa.Contrib.Globalization.I18N/README.md | 4 ++-- .../README.zh-CN.md | 10 +++++----- .../_Imports.cs | 2 +- .../Resources/{I18n => I18N2}/en-US.json | 0 .../{I18n => I18N2}/supportedCultures.json | 0 .../Resources/{I18n => I18N2}/zh-CN.json | 0 .../I18nTest.cs | 2 +- 16 files changed, 44 insertions(+), 44 deletions(-) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/{I18n => I18N2}/en-US.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/{I18n => I18N2}/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/{I18n => I18N2}/zh-CN.json (100%) diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index 6abdfe711..57d74b810 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -32,25 +32,25 @@ internal II18N? I18N } } - private II18N? _frameworkI18n; + private II18N? _frameworkI18N; - internal II18N? FrameworkI18n + internal II18N? FrameworkI18N { get { TryInitialize(); - return _frameworkI18n; + return _frameworkI18N; } } - private bool _supportI18n; + private bool _supportI18N; - internal bool SupportI18n + internal bool SupportI18N { get { TryInitialize(); - return _supportI18n; + return _supportI18N; } } @@ -64,9 +64,9 @@ private void TryInitialize() private void Initialize() { - _frameworkI18n = MasaApp.GetService>(); + _frameworkI18N = MasaApp.GetService>(); _i18N = MasaApp.GetService>(); - _supportI18n = _frameworkI18n != null; + _supportI18N = _frameworkI18N != null; _initialize = true; } @@ -111,7 +111,7 @@ public string GetLocalizedMessage() protected virtual string GetLocalizedMessageExecuting() { - if (!SupportI18n) + if (!SupportI18N) { if (string.IsNullOrWhiteSpace(ErrorMessage)) return Message; @@ -122,7 +122,7 @@ protected virtual string GetLocalizedMessageExecuting() if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) { //The current framework frame exception - return FrameworkI18n!.T(ErrorCode!, false, GetParameters()) ?? Message; + return FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; } return I18N!.T(ErrorCode, false, GetParameters()) ?? Message; diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs index a2716c2de..a8fb1c025 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs @@ -192,7 +192,7 @@ private static void Throw( protected override string GetLocalizedMessageExecuting() { string message; - if (!SupportI18n) + if (!SupportI18N) { message = string.IsNullOrWhiteSpace(ErrorMessage) ? Message : string.Format(ErrorMessage, GetParameters()); } @@ -200,7 +200,7 @@ protected override string GetLocalizedMessageExecuting() else if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) { //The current framework frame exception - message = FrameworkI18n!.T(ErrorCode!, false, GetParameters()) ?? Message; + message = FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; } else { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs index efb2a16f1..7036d644f 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs @@ -6,10 +6,10 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public static class I18N { private static readonly IServiceProvider _serviceProvider = MasaApp.RootServiceProvider; - private static readonly II18N Ii18N = InitI18n(); + private static readonly II18N Ii18N = InitI18N(); private static readonly ILanguageProvider _languageProvider = InitLanguage(); - static II18N InitI18n() => _serviceProvider.GetRequiredService(); + static II18N InitI18N() => _serviceProvider.GetRequiredService(); static ILanguageProvider InitLanguage() => _serviceProvider.GetRequiredService(); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index 637ace2f0..e13492d28 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -21,7 +21,7 @@ public static IApplicationBuilder UseMasaExceptionHandler( var option = new MasaExceptionHandlerOptions(); exceptionHandlingOptions?.Invoke(option); - app.UseI18n(); + app.UseI18N(); app.UseMiddleware(Options.Create(option)); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index ce7a6e156..2ba24e8f2 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -27,7 +27,7 @@ public ExceptionHandlerMiddleware( public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceProvider) { - var frameworkI18n = serviceProvider.GetService>(); + var frameworkI18N = serviceProvider.GetService>(); try { await _next(httpContext); @@ -67,8 +67,8 @@ await httpContext.Response.WriteTextAsync( } else if (_options.CatchAllException) { - string message = frameworkI18n == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : - frameworkI18n[ErrorCode.INTERNAL_SERVER_ERROR]; + string message = frameworkI18N == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : + frameworkI18N[ErrorCode.INTERNAL_SERVER_ERROR]; await httpContext.Response.WriteTextAsync(httpStatusCode, message); } else diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index dfac8bc07..9f47b6a1f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -10,7 +10,7 @@ public static class ApplicationBuilderExtensions { private static bool _isInitialize; - public static IApplicationBuilder UseI18n(this IApplicationBuilder app) + public static IApplicationBuilder UseI18N(this IApplicationBuilder app) { if (_isInitialize) return app; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md index 6e27b173b..7d164723f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md @@ -76,18 +76,18 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore 2. Register to use I18N, modify `Program.cs` ``` C# -services.AddI18n(); +services.AddI18N(); ``` 3. Use `Masa.Contrib.Globalization.I18N.AspNetCore` to provide the ability to parse Culture ``` C# -app.UseI18n(); +app.UseI18N(); ``` 4. How to use I18N -* Get `II18n` from DI (**II18n** is the interface, supports getting from DI) +* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) * Use `I18N` (**I18N** is a static class) Take `I18N` as an example: diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md index bf90e5b85..8618289c3 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md @@ -73,21 +73,21 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore ] ``` -2. 注册使用I18n, 修改`Program.cs` +2. 注册使用I18N, 修改`Program.cs` ``` C# -services.AddI18n(); +services.AddI18N(); ``` 3. 使用`Masa.Contrib.Globalization.I18N.AspNetCore`提供解析Culture的能力 ``` C# -app.UseI18n(); +app.UseI18N(); ``` -4. 如何使用I18n +4. 如何使用I18N -* 从DI获取`II18n` (**II18n**是接口,支持从DI获取) +* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) * 使用`I18N` (**I18N**是静态类) 以`I18N`为例: diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index b813f5c87..74d0045ea 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -31,7 +31,7 @@ public static IServiceCollection AddI18NByEmbedded( settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18nConstant.SUPPORTED_CULTURES_NAME : + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : supportCultureName; }, action); } @@ -59,7 +59,7 @@ public static IServiceCollection TestAddI18N( return services.TestAddI18N(settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18nConstant.SUPPORTED_CULTURES_NAME : + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : supportCultureName; settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); @@ -88,21 +88,21 @@ private static IServiceCollection AddI18NByFramework(this IServiceCollection ser options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18nConstant.DefaultFrameworkResourcePath, + resource.AddJson(ContribI18NConstant.DefaultFrameworkResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18nConstant.DefaultFrameworkParameterValidationResourcePath, + resource.AddJson(ContribI18NConstant.DefaultFrameworkParameterValidationResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18nConstant.DefaultFrameworkLanguageResourcePath, + resource.AddJson(ContribI18NConstant.DefaultFrameworkLanguageResourcePath, languageSettings.SupportedCultures); }); }); @@ -118,10 +118,10 @@ private static CultureSettings AddAndGetCultureSettings( settingsAction?.Invoke(settings); if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) - settings.ResourcesDirectory = ContribI18nConstant.DefaultResourcePath; + settings.ResourcesDirectory = ContribI18NConstant.DefaultResourcePath; if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) - settings.SupportCultureName = ContribI18nConstant.SUPPORTED_CULTURES_NAME; + settings.SupportCultureName = ContribI18NConstant.SUPPORTED_CULTURES_NAME; if (!settings.SupportedCultures.Any()) settings.SupportedCultures = @@ -151,7 +151,7 @@ private static IServiceCollection AddI18NCore( options.Resources.TryAdd(resource => { if (assemblies.Any()) resource.Assemblies = assemblies; - resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18nConstant.DefaultResourcePath, + resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, localLanguageSettings.SupportedCultures); }); }); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md index c3fc4663a..1b9635bfe 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md @@ -72,12 +72,12 @@ Install-Package Masa.Contrib.Globalization.I18N 2. Register to use I18N, modify `Program.cs` ``` C# -services.AddI18n(); +services.AddI18N(); ``` 3. How to use I18N -* Get `II18n` from DI (**II18n** is the interface, supports getting from DI) +* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) * Use `I18N` (**I18N** is a static class) Take `I18N` as an example: diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md index d200f241e..36d4266b9 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md @@ -69,15 +69,15 @@ Install-Package Masa.Contrib.Globalization.I18N ] ``` -2. 注册使用I18n, 修改`Program.cs` +2. 注册使用I18N, 修改`Program.cs` ``` C# -services.AddI18n(); +services.AddI18N(); ``` -3. 如何使用I18n +3. 如何使用I18N -* 从DI获取`II18n` (**II18n**是接口,支持从DI获取) +* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) * 使用`I18N` (**I18N**是静态类) 以`I18N`为例: @@ -87,7 +87,7 @@ var home = I18N.T("Home"); //获取键值Home对应语言的值,此方法调 var name = I18N.T("User.Name");//输出:名称(支持嵌套) ``` -### I18n提供 +### I18N提供 * SetCulture (string cultureName): 将CurrentCulture切换成zh-CN,它更改后数字、日期等表示格式也随之改变 * SetUiCulture (string cultureName): 将界面语言(CurrentUICulture)切换成zh-CN diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs index 67e25bb54..eaab79eb6 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs @@ -15,5 +15,5 @@ global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; global using System.Reflection; -global using ContribI18nConstant = Masa.Contrib.Globalization.I18N.Constant; +global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; global using MasaJsonConfigurationSource = Masa.Contrib.Globalization.I18N.Json.JsonConfigurationSource; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18n/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs index e494df7bd..658d09606 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs @@ -4,7 +4,7 @@ namespace Masa.Contrib.Globalization.I18N.Tests; [TestClass] -public class I18nTest +public class I18NTest { private const string DEFAULT_RESOURCE = "Resources/I18N"; From 7cec5133881362b412668b4c2048b9d692a8f424 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 10 Nov 2022 15:21:03 +0800 Subject: [PATCH 33/38] rename: I18n -> I18N --- .../Resources/{I18n => I18N}/Framework/Languages/en-US.json | 0 .../Resources/{I18n => I18N}/Framework/Languages/zh-CN.json | 0 .../{I18n => I18N}/Framework/ParameterValidations/en-US.json | 0 .../{I18n => I18N}/Framework/ParameterValidations/zh-CN.json | 0 .../Resources/{I18n => I18N}/Framework/en-US.json | 0 .../Resources/{I18n => I18N}/Framework/zh-CN.json | 0 .../Resources/{I18N2 => I18N}/en-US.json | 0 .../Resources/{I18N2 => I18N}/supportedCultures.json | 0 .../Resources/{I18N2 => I18N}/zh-CN.json | 0 .../Resources/{I18n => I18N}/en-US.json | 0 .../Resources/{I18n => I18N}/supportedCultures.json | 0 .../Resources/{I18n => I18N}/zh-CN.json | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{I18n => I18N}/Framework/Languages/en-US.json (100%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{I18n => I18N}/Framework/Languages/zh-CN.json (100%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{I18n => I18N}/Framework/ParameterValidations/en-US.json (100%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{I18n => I18N}/Framework/ParameterValidations/zh-CN.json (100%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{I18n => I18N}/Framework/en-US.json (100%) rename src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/{I18n => I18N}/Framework/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/{I18N2 => I18N}/en-US.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/{I18N2 => I18N}/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/{I18N2 => I18N}/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{I18n => I18N}/en-US.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{I18n => I18N}/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/{I18n => I18N}/zh-CN.json (100%) diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/Languages/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/ParameterValidations/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18n/Framework/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N2/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18n/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/zh-CN.json From 59d80b2f9214563b693c4ea22b12063f50eceaec Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 10 Nov 2022 17:05:54 +0800 Subject: [PATCH 34/38] chore: fix bad code smell --- .../MasaArgumentExceptionTest.cs | 2 +- .../MasaArgumentException.cs | 76 ++++++++++++++----- .../MasaException.cs | 33 +++++--- .../MasaValidatorException.cs | 41 ++++++---- .../UserFriendlyException.cs | 27 ++++++- .../I18NResourceDictionary.cs | 6 ++ .../I18nOfT.cs | 2 +- .../II18NOfT.cs | 2 +- .../_Imports.cs | 1 + .../DefaultRequestMessage.cs | 6 +- .../DefaultResponseMessage.cs | 66 ++++++++++------ .../Masa.Contrib.Service.Caller/_Imports.cs | 1 + .../DefaultRequestMessageTest.cs | 30 ++++++++ .../JsonDefaultRequestMessage.cs | 17 +++++ 14 files changed, 232 insertions(+), 78 deletions(-) create mode 100644 src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultRequestMessageTest.cs create mode 100644 src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/JsonDefaultRequestMessage.cs diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs index 5bf2cdc54..eb72cda6a 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions.Tests/MasaArgumentExceptionTest.cs @@ -20,7 +20,7 @@ public void TestThrowIfNull() catch (MasaArgumentException ex) { Assert.AreEqual(Data.Constants.ErrorCode.NOT_NULL_VALIDATOR, ex.ErrorCode); - Assert.AreEqual("'{0}' must not be empty.", ex.ErrorMessage); + Assert.AreEqual("'{0}' must not be empty.", ex.GetErrorMessage()); } } } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs index bd49b1fba..b4ce32027 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaArgumentException.cs @@ -8,36 +8,50 @@ namespace System; [Serializable] public class MasaArgumentException : MasaException { - protected string? ParamName { get; } + private string? _paramName; + protected string? ParamName => _paramName; - public MasaArgumentException(string message) - : base(message) + public MasaArgumentException( + string message, + LogLevel? logLevel = null) + : base(message, logLevel) { } - public MasaArgumentException(string message, string paramName) - : base(message) + public MasaArgumentException( + string message, + string paramName, + LogLevel? logLevel = null) + : base(message, logLevel) { - ParamName = paramName; + _paramName = paramName; } - public MasaArgumentException(string? paramName, string errorCode, params object[] parameters) - : this((Exception?)null, errorCode, parameters) + public MasaArgumentException( + string? paramName, + string errorCode, + LogLevel? logLevel = null, + params object[] parameters) + : this((Exception?)null, errorCode, logLevel, parameters) { - ParamName = paramName; + _paramName = paramName; } - public MasaArgumentException(Exception? innerException, string errorCode, params object[] parameters) - : base(innerException, errorCode, parameters) + public MasaArgumentException( + Exception? innerException, + string errorCode, + LogLevel? logLevel = null, + params object[] parameters) + : base(innerException, errorCode, logLevel, parameters) { } - public MasaArgumentException(string message, Exception? innerException) - : base(message, innerException) + public MasaArgumentException(string message, Exception? innerException, LogLevel? logLevel = null) + : base(message, innerException, logLevel) { } - public MasaArgumentException(SerializationInfo serializationInfo, StreamingContext context) + protected MasaArgumentException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) { } @@ -79,6 +93,7 @@ public static void ThrowIfGreaterThan(T argument, ThrowIf(argument.CompareTo(maxValue) > 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_OR_EQUAL_VALIDATOR, + null, maxValue); } @@ -89,6 +104,7 @@ public static void ThrowIfGreaterThanOrEqual(T argument, ThrowIf(argument.CompareTo(maxValue) >= 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_VALIDATOR, + null, maxValue); } @@ -99,6 +115,7 @@ public static void ThrowIfLessThan(T argument, ThrowIf(argument.CompareTo(minValue) < 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_OR_EQUAL_VALIDATOR, + null, minValue); } @@ -109,6 +126,7 @@ public static void ThrowIfLessThanOrEqual(T argument, ThrowIf(argument.CompareTo(minValue) <= 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_VALIDATOR, + null, minValue); } @@ -120,6 +138,7 @@ public static void ThrowIfOutOfRange(T argument, ThrowIf(argument.CompareTo(minValue) < 0 || argument.CompareTo(maxValue) > 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.OUT_OF_RANGE_VALIDATOR, + null, minValue, maxValue); } @@ -141,19 +160,36 @@ public static void ThrowIfContain(string? argument, ); } - public static void ThrowIf(bool condition, string? paramName, string errorCode, params object[] parameters) + public static void ThrowIf( + bool condition, + string? paramName, + string errorCode, + LogLevel? logLevel = null, + params object[] parameters) { - if (condition) Throw(paramName, errorCode, Masa.BuildingBlocks.Data.Constants.ErrorCode.GetErrorMessage(errorCode), parameters); + if (condition) + Throw(paramName, errorCode, Masa.BuildingBlocks.Data.Constants.ErrorCode.GetErrorMessage(errorCode), logLevel, parameters); } - public static void ThrowIf(bool condition, string? paramName, string errorCode, string? errorMessage, params object[] parameters) + public static void ThrowIf( + bool condition, + string? paramName, + string errorCode, + string? errorMessage, + LogLevel? logLevel = null, + params object[] parameters) { - if (condition) Throw(paramName, errorCode, errorMessage, parameters); + if (condition) Throw(paramName, errorCode, errorMessage, logLevel, parameters); } [DoesNotReturn] - private static void Throw(string? paramName, string errorCode, string? errorMessage, params object[] parameters) => - throw new MasaArgumentException(paramName, errorCode, parameters) + private static void Throw( + string? paramName, + string errorCode, + string? errorMessage, + LogLevel? logLevel, + params object[] parameters) => + throw new MasaArgumentException(paramName, errorCode, logLevel, parameters) { ErrorMessage = errorMessage }; diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index 57d74b810..1ea89cfcd 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -8,16 +8,20 @@ namespace System; [Serializable] public class MasaException : Exception { - public virtual LogLevel? LogLevel { get; set; } + private LogLevel? _logLevel; + public LogLevel? LogLevel => _logLevel; - public string? ErrorCode { get; private set; } + private string? _errorCode; + public string? ErrorCode => _errorCode; /// /// Provides error message that I18N is not used /// - public string? ErrorMessage { get; set; } + protected string? ErrorMessage { get; set; } - public object[] Parameters { get; private set; } + private object[] _parameters; + + public object[] Parameters => _parameters; private bool _initialize; @@ -74,29 +78,32 @@ public MasaException() { } - public MasaException(string message) + public MasaException(string message, LogLevel? logLevel = null) : base(message) { + _logLevel = logLevel; } - public MasaException(string errorCode, params object[] parameters) - : this(null, errorCode, parameters) + public MasaException(string errorCode, LogLevel? logLevel = null, params object[] parameters) + : this(null, errorCode, logLevel, parameters) { } - public MasaException(Exception? innerException, string errorCode, params object[] parameters) + public MasaException(Exception? innerException, string errorCode, LogLevel? logLevel = null, params object[] parameters) : base(null, innerException) { - ErrorCode = errorCode; - Parameters = parameters; + _errorCode = errorCode; + _parameters = parameters; + _logLevel = logLevel; } - public MasaException(string message, Exception? innerException) + public MasaException(string message, Exception? innerException, LogLevel? logLevel = null) : base(message, innerException) { + _logLevel = logLevel; } - public MasaException(SerializationInfo serializationInfo, StreamingContext context) + protected MasaException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) { } @@ -129,4 +136,6 @@ protected virtual string GetLocalizedMessageExecuting() } protected virtual object[] GetParameters() => Parameters; + + public string? GetErrorMessage() => ErrorMessage; } diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs index a8fb1c025..d9df2d6c7 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs @@ -8,34 +8,40 @@ namespace System; [Serializable] public class MasaValidatorException : MasaArgumentException { - public MasaValidatorException(string message) - : base(message) + public MasaValidatorException(string message, LogLevel? logLevel = null) + : base(message, logLevel) { } - public MasaValidatorException(string? paramName, string errorCode, params object[] parameters) - : base(paramName, errorCode, parameters) + public MasaValidatorException(string? paramName, string errorCode, LogLevel? logLevel = null, params object[] parameters) + : base(paramName, errorCode, logLevel, parameters) { } - public MasaValidatorException(Exception? innerException, string errorCode, params object[] parameters) - : base(innerException, errorCode, parameters) + public MasaValidatorException(Exception? innerException, string errorCode, LogLevel? logLevel = null, params object[] parameters) + : base(innerException, errorCode, logLevel, parameters) { } public MasaValidatorException(params ValidationModel[] validationModels) - : base(FormatMessage(validationModels)) + : base(FormatMessage(validationModels), Microsoft.Extensions.Logging.LogLevel.Error) { } - public MasaValidatorException(string message, Exception? innerException) - : base(message, innerException) + public MasaValidatorException(LogLevel? logLevel = null, params ValidationModel[] validationModels) + : base(FormatMessage(validationModels), logLevel) + { + + } + + public MasaValidatorException(string message, Exception? innerException, LogLevel? logLevel = null) + : base(message, innerException, logLevel) { } - public MasaValidatorException(SerializationInfo serializationInfo, StreamingContext context) + protected MasaValidatorException(SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) { } @@ -97,6 +103,7 @@ private static string FormatMessage(IEnumerable models) ThrowIf(argument.CompareTo(maxValue) > 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_OR_EQUAL_VALIDATOR, + null, maxValue); } @@ -107,6 +114,7 @@ private static string FormatMessage(IEnumerable models) ThrowIf(argument.CompareTo(maxValue) >= 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.LESS_THAN_VALIDATOR, + null, maxValue); } @@ -117,6 +125,7 @@ private static string FormatMessage(IEnumerable models) ThrowIf(argument.CompareTo(minValue) < 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_OR_EQUAL_VALIDATOR, + null, minValue); } @@ -127,6 +136,7 @@ private static string FormatMessage(IEnumerable models) ThrowIf(argument.CompareTo(minValue) <= 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.GREATER_THAN_VALIDATOR, + null, minValue); } @@ -138,6 +148,7 @@ private static string FormatMessage(IEnumerable models) ThrowIf(argument.CompareTo(minValue) < 0 || argument.CompareTo(maxValue) > 0, paramName, Masa.BuildingBlocks.Data.Constants.ErrorCode.OUT_OF_RANGE_VALIDATOR, + null, minValue, maxValue); } @@ -163,9 +174,11 @@ private static string FormatMessage(IEnumerable models) bool condition, string? paramName, string errorCode, + LogLevel? logLevel = null, params object[] parameters) { - if (condition) Throw(paramName, errorCode, Masa.BuildingBlocks.Data.Constants.ErrorCode.GetErrorMessage(errorCode), parameters); + if (condition) + Throw(paramName, errorCode, Masa.BuildingBlocks.Data.Constants.ErrorCode.GetErrorMessage(errorCode), logLevel, parameters); } public new static void ThrowIf( @@ -173,9 +186,10 @@ private static string FormatMessage(IEnumerable models) string? paramName, string errorCode, string? errorMessage, + LogLevel? logLevel = null, params object[] parameters) { - if (condition) Throw(paramName, errorCode, errorMessage, parameters); + if (condition) Throw(paramName, errorCode, errorMessage, logLevel, parameters); } [DoesNotReturn] @@ -183,8 +197,9 @@ private static void Throw( string? paramName, string errorCode, string? errorMessage, + LogLevel? logLevel, params object[] parameters) - => throw new MasaValidatorException(paramName, errorCode, parameters) + => throw new MasaValidatorException(paramName, errorCode, logLevel, parameters) { ErrorMessage = errorMessage }; diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs index 900f50333..88c13c01f 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/UserFriendlyException.cs @@ -18,13 +18,32 @@ public UserFriendlyException(string message, Exception? innerException) { } - public UserFriendlyException(string errorCode, string errorMessage, params object[] parameters) - : base(errorCode, errorMessage, parameters) + public UserFriendlyException( + string errorCode, + params object[] parameters) + : base(errorCode, null, parameters) { } - public UserFriendlyException(Exception? innerException, string errorCode, string errorMessage, params object[] parameters) - : base(innerException, errorCode, errorMessage, parameters) + public UserFriendlyException( + string errorCode, + LogLevel? logLevel, + params object[] parameters) + : base(errorCode, logLevel, parameters) + { + } + + public UserFriendlyException( + Exception? innerException, + string errorCode, + LogLevel? logLevel = null, + params object[] parameters) + : base(innerException, errorCode, logLevel, parameters) + { + } + + protected UserFriendlyException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) { } } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs index 5a7a0cc86..b86e73543 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs @@ -6,6 +6,12 @@ namespace Masa.BuildingBlocks.Globalization.I18N; [Serializable] public class I18NResourceDictionary : Dictionary { + public I18NResourceDictionary() + { + } + + protected I18NResourceDictionary(SerializationInfo info, StreamingContext context) : base(info, context){} + public I18NResource Add(params Type[] baseResourceTypes) { return Add(typeof(TResource), baseResourceTypes); diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs index 92a3e4ff9..b760b994f 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs @@ -3,7 +3,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public class I18N : II18N where TResourceSource : class +public class I18N : II18N { private readonly I18NResource? _resource; private readonly List _baseResources; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs index 294071619..0a32bf50c 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs @@ -3,7 +3,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; -public interface II18N : II18N where TResourceSource : class +public interface II18N : II18N { } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs index 4e28edc68..b1d03ba60 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs @@ -6,3 +6,4 @@ global using Microsoft.Extensions.Options; global using System.Globalization; global using System.Reflection; +global using System.Runtime.Serialization; diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs index 475cd4cff..b6352cdd8 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultRequestMessage.cs @@ -1,8 +1,6 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -using System.Globalization; - namespace Masa.Contrib.Service.Caller; public abstract class DefaultRequestMessage @@ -51,7 +49,9 @@ protected virtual void TrySetCulture(HttpRequestMessage requestMessage, List<(st requestMessage.Headers.Remove(name); string value = System.Web.HttpUtility.UrlEncode(string.Join('|', cultures.Select(c => $"{c.Key}={c.Value}"))); var cookies = cookieValues?.ToList() ?? new List(); - cookies.Add($".AspNetCore.Culture={value}"); + if (!cookies.Any(cookie => cookie.Contains(".AspNetCore.Culture=", StringComparison.OrdinalIgnoreCase))) + cookies.Add($".AspNetCore.Culture={value}"); + requestMessage.Headers.Add(name, cookies); } } diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs index d54cae82f..ee5b8cc2c 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/DefaultResponseMessage.cs @@ -56,40 +56,23 @@ public async Task ProcessResponseExceptionAsync(HttpResponseMessage response, Ca throw new MasaException($"ReasonPhrase: {response.ReasonPhrase ?? string.Empty}, StatusCode: {response.StatusCode}"); } - private async Task FormatResponseAsync(HttpResponseMessage response, + private async Task FormatResponseAsync( + HttpResponseMessage response, CancellationToken cancellationToken = default) { var responseType = typeof(TResponse); if (responseType == typeof(Guid) || responseType == typeof(Guid?)) - { - var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); - if (IsNullOrEmpty(content)) - return default; + return await FormatResponseByGuidAsync(response, cancellationToken); - return (TResponse?)(object)Guid.Parse(content); - } if (responseType == typeof(DateTime) || responseType == typeof(DateTime?)) - { - var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); - if (IsNullOrEmpty(content)) - return default; - - return (TResponse?)(object)DateTime.Parse(content); - } + return await FormatResponseByDateTimeAsync(response, cancellationToken); var actualType = Nullable.GetUnderlyingType(responseType); if (responseType.GetInterfaces().Any(type => type == typeof(IConvertible)) || (actualType != null && actualType.GetInterfaces().Any(type => type == typeof(IConvertible)))) { - var content = await response.Content.ReadAsStringAsync(cancellationToken); - if (IsNullOrEmpty(content)) - return default; - - if (actualType != null) - return (TResponse?)Convert.ChangeType(content, actualType); - - return (TResponse?)Convert.ChangeType(content, responseType); + return await FormatResponseByValueTypeAsync(responseType, actualType, response, cancellationToken); } try @@ -100,11 +83,48 @@ public async Task ProcessResponseExceptionAsync(HttpResponseMessage response, Ca } catch (Exception exception) { - _logger?.LogWarning(exception, exception.Message); + _logger?.LogWarning(exception, "{Message}", exception.Message); ExceptionDispatchInfo.Capture(exception).Throw(); return default; //This will never be executed, the previous line has already thrown an exception } } + private static async Task FormatResponseByGuidAsync( + HttpResponseMessage response, + CancellationToken cancellationToken = default) + { + var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); + if (IsNullOrEmpty(content)) + return default; + + return (TResponse?)(object)Guid.Parse(content); + } + + private static async Task FormatResponseByDateTimeAsync(HttpResponseMessage response, + CancellationToken cancellationToken = default) + { + var content = (await response.Content.ReadAsStringAsync(cancellationToken)).Replace("\"", ""); + if (IsNullOrEmpty(content)) + return default; + + return (TResponse?)(object)DateTime.Parse(content); + } + + private static async Task FormatResponseByValueTypeAsync( + Type responseType, + Type? actualType, + HttpResponseMessage response, + CancellationToken cancellationToken = default) + { + var content = await response.Content.ReadAsStringAsync(cancellationToken); + if (IsNullOrEmpty(content)) + return default; + + if (actualType != null) + return (TResponse?)Convert.ChangeType(content, actualType); + + return (TResponse?)Convert.ChangeType(content, responseType); + } + private static bool IsNullOrEmpty(string value) => string.IsNullOrEmpty(value) || value == "null"; } diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs index cbd8cef90..60b4a2f0d 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller/_Imports.cs @@ -12,6 +12,7 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using System.Collections.Concurrent; +global using System.Globalization; global using System.Net; global using System.Net.Http.Json; global using System.Reflection; diff --git a/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultRequestMessageTest.cs b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultRequestMessageTest.cs new file mode 100644 index 000000000..bac2c855e --- /dev/null +++ b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultRequestMessageTest.cs @@ -0,0 +1,30 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Service.Caller.Tests; + +[TestClass] +public class DefaultRequestMessageTest +{ + [TestMethod] + public void TestTrySetCulture() + { + var services = new ServiceCollection(); + services.AddHttpContextAccessor(); + var requestMessage = new JsonDefaultRequestMessage(services.BuildServiceProvider()); + + var httpRequestMessage = new HttpRequestMessage(); + var value = " .AspNetCore.Culture=te"; + httpRequestMessage.Headers.Add("cookie", new List() + { + value + }); + requestMessage.TestTrySetCulture(httpRequestMessage, new List<(string Key, string Value)>() + { + ("c", "en-US"), + ("uic", "en-US") + }); + var cookies = httpRequestMessage.Headers.GetValues("cookie").ToList(); + Assert.IsTrue(cookies.Contains(value)); + } +} diff --git a/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/JsonDefaultRequestMessage.cs b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/JsonDefaultRequestMessage.cs new file mode 100644 index 000000000..46a2f8eff --- /dev/null +++ b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/JsonDefaultRequestMessage.cs @@ -0,0 +1,17 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Service.Caller.Tests; + +public class JsonDefaultRequestMessage : DefaultRequestMessage +{ + public JsonDefaultRequestMessage(IServiceProvider serviceProvider, IOptions? options = null) + : base(serviceProvider, options) + { + } + + public void TestTrySetCulture(HttpRequestMessage requestMessage, List<(string Key, string Value)> cultures) + { + base.TrySetCulture(requestMessage, cultures); + } +} From 9827b817934c65fa189d64232a698c38a0259eb7 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Fri, 11 Nov 2022 09:05:06 +0800 Subject: [PATCH 35/38] chore: Adjust the default Culture --- .../CultureSettings.cs | 2 -- .../Extensions/ApplicationBuilderExtensions.cs | 8 +++++--- .../Extensions/ApplicationBuilderExtensions.cs | 5 ++--- .../Extensions/ServiceCollectionExtensions.cs | 6 ------ 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs index 6e4be2602..7ed76b36f 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs @@ -5,8 +5,6 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public class CultureSettings { - public string DefaultCulture { get; set; } - public string? ResourcesDirectory { get; set; } public string? SupportCultureName { get; set; } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index e13492d28..702030027 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -9,19 +9,21 @@ namespace Microsoft.AspNetCore.Builder; public static class ApplicationBuilderExtensions { /// - /// Use localizable + /// Use I18N /// /// /// + /// /// public static IApplicationBuilder UseMasaExceptionHandler( this IApplicationBuilder app, - Action? exceptionHandlingOptions = null) + Action? exceptionHandlingOptions = null, + string? defaultCulture = null) { var option = new MasaExceptionHandlerOptions(); exceptionHandlingOptions?.Invoke(option); - app.UseI18N(); + app.UseI18N(defaultCulture); app.UseMiddleware(Options.Create(option)); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index 9f47b6a1f..edc1ce186 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -10,7 +10,7 @@ public static class ApplicationBuilderExtensions { private static bool _isInitialize; - public static IApplicationBuilder UseI18N(this IApplicationBuilder app) + public static IApplicationBuilder UseI18N(this IApplicationBuilder app, string? defaultCulture = null) { if (_isInitialize) return app; @@ -24,8 +24,7 @@ public static IApplicationBuilder UseI18N(this IApplicationBuilder app) requestLocalization .AddSupportedCultures(cultures) .AddSupportedUICultures(cultures); - if (!string.IsNullOrWhiteSpace(settings.DefaultCulture)) - requestLocalization.SetDefaultCulture(settings.DefaultCulture); + requestLocalization.SetDefaultCulture(!string.IsNullOrWhiteSpace(defaultCulture) ? defaultCulture : cultures.FirstOrDefault()!); requestLocalization.ApplyCurrentCultureToResponseHeaders = true; app.UseRequestLocalization(requestLocalization); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs index 74d0045ea..f99dcc8a4 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs @@ -62,9 +62,6 @@ public static IServiceCollection TestAddI18N( settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : supportCultureName; settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); - - if (string.IsNullOrEmpty(settings.DefaultCulture)) - settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; }, action); } @@ -126,9 +123,6 @@ private static CultureSettings AddAndGetCultureSettings( if (!settings.SupportedCultures.Any()) settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName); - - if (string.IsNullOrEmpty(settings.DefaultCulture)) - settings.DefaultCulture = settings.SupportedCultures.Select(c => c.Culture).FirstOrDefault()!; }); var serviceProvider = services.BuildServiceProvider(); return serviceProvider.GetRequiredService>().Value; From 2eebad011d3f42ae5e1b746b2e9c4703caab5417 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Fri, 11 Nov 2022 11:56:48 +0800 Subject: [PATCH 36/38] chore: Optimize the experience --- .../Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index 1ea89cfcd..edef2c0d6 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -84,7 +84,7 @@ public MasaException(string message, LogLevel? logLevel = null) _logLevel = logLevel; } - public MasaException(string errorCode, LogLevel? logLevel = null, params object[] parameters) + public MasaException(string errorCode, LogLevel? logLevel, params object[] parameters) : this(null, errorCode, logLevel, parameters) { } From 85f68419400036ff4c9df836d9a0e3dc45cf0506 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Fri, 11 Nov 2022 16:18:24 +0800 Subject: [PATCH 37/38] chore: fix bad code smell --- .../I18N.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs index 7036d644f..254effc2a 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs @@ -6,7 +6,7 @@ namespace Masa.BuildingBlocks.Globalization.I18N; public static class I18N { private static readonly IServiceProvider _serviceProvider = MasaApp.RootServiceProvider; - private static readonly II18N Ii18N = InitI18N(); + private static readonly II18N _i18N = InitI18N(); private static readonly ILanguageProvider _languageProvider = InitLanguage(); static II18N InitI18N() => _serviceProvider.GetRequiredService(); @@ -18,7 +18,7 @@ public static class I18N /// /// The name of the string resource. /// - public static string T(string name) => Ii18N.T(name); + public static string T(string name) => _i18N.T(name); /// /// Gets the string resource with the given name. @@ -26,14 +26,14 @@ public static class I18N /// The name of the string resource. /// Return Key when key does not exist, default: true /// - public static string? T(string name, bool returnKey) => Ii18N.T(name, returnKey); + public static string? T(string name, bool returnKey) => _i18N.T(name, returnKey); /// /// Gets the string resource with the given name and formatted with the supplied arguments. /// /// The name of the string resource. /// The values to format the string with. - public static string T(string name, params object[] arguments) => Ii18N.T(name, arguments); + public static string T(string name, params object[] arguments) => _i18N.T(name, arguments); /// /// Gets the string resource with the given name and formatted with the supplied arguments. @@ -41,9 +41,9 @@ public static class I18N /// The name of the string resource. /// Return Key when key does not exist, default: true /// The values to format the string with. - public static string? T(string name, bool returnKey, params object[] arguments) => Ii18N.T(name, returnKey, arguments); + public static string? T(string name, bool returnKey, params object[] arguments) => _i18N.T(name, returnKey, arguments); - public static CultureInfo GetCultureInfo() => Ii18N.GetCultureInfo(); + public static CultureInfo GetCultureInfo() => _i18N.GetCultureInfo(); /// /// Set the CultureName @@ -51,20 +51,20 @@ public static class I18N /// /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). - public static void SetCulture(string cultureName, bool useUserOverride = true) => Ii18N.SetCulture(cultureName, useUserOverride); + public static void SetCulture(string cultureName, bool useUserOverride = true) => _i18N.SetCulture(cultureName, useUserOverride); /// /// Set the CultureName /// Data used to define "regional options", standards, formats, etc /// /// - public static void SetCulture(CultureInfo culture) => Ii18N.SetCulture(culture); + public static void SetCulture(CultureInfo culture) => _i18N.SetCulture(culture); /// /// get interface language /// /// - public static CultureInfo GetUiCultureInfo() => Ii18N.GetUiCultureInfo(); + public static CultureInfo GetUiCultureInfo() => _i18N.GetUiCultureInfo(); /// /// Set the CultureName for the current request @@ -72,14 +72,14 @@ public static class I18N /// /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). - public static void SetUiCulture(string cultureName, bool useUserOverride = true) => Ii18N.SetUiCulture(cultureName, useUserOverride); + public static void SetUiCulture(string cultureName, bool useUserOverride = true) => _i18N.SetUiCulture(cultureName, useUserOverride); /// /// Set the CultureName for the current request /// Used to set the interface language /// /// - public static void SetUiCulture(CultureInfo culture) => Ii18N.SetUiCulture(culture); + public static void SetUiCulture(CultureInfo culture) => _i18N.SetUiCulture(culture); public static IReadOnlyList GetLanguages() => _languageProvider.GetLanguages(); } From c8b21a336748fba65fe0ad554364b65623b1d44d Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 14 Nov 2022 09:51:18 +0800 Subject: [PATCH 38/38] rename: I18N -> I18n --- Masa.Framework.sln | 12 +-- .../Constants/ErrorCode.cs | 11 +-- .../Masa.BuildingBlocks.Exceptions.csproj | 2 +- .../MasaException.cs | 32 ++++---- .../MasaValidatorException.cs | 6 +- .../_Imports.cs | 2 +- .../Constant.cs | 4 +- .../CultureModel.cs | 2 +- .../CultureSettings.cs | 2 +- .../DefaultLanguageProvider.cs | 12 +-- .../I18n.cs} | 28 +++---- .../I18nOfT.cs | 22 +++--- .../I18nResource.cs} | 12 +-- .../I18nResourceDictionary.cs} | 34 ++++---- .../I18nResourceResourceConfiguration.cs} | 6 +- .../II18n.cs} | 4 +- .../II18nOfT.cs} | 4 +- .../II18nResourceContributor.cs} | 4 +- .../ILanguageProvider.cs | 2 +- .../InheritResourceAttribute.cs | 2 +- .../LanguageInfo.cs | 2 +- ....BuildingBlocks.Globalization.I18n.csproj} | 0 .../Options/I18nOptions.cs} | 6 +- .../Options/MasaI18nOptions.cs} | 8 +- .../Resources/DefaultResource.cs | 2 +- .../Resources/MasaFrameworkResource.cs | 2 +- .../Resources/MasaLanguageResource.cs | 2 +- .../MasaParameterValidationResource.cs | 2 +- .../_Imports.cs | 0 .../ApplicationBuilderExtensions.cs | 4 +- .../Handlers/ExceptionHandlerMiddleware.cs | 6 +- .../Handlers/MvcGlobalExceptionFilter.cs | 10 +-- .../Masa.Contrib.Exceptions.csproj | 4 +- .../MasaExceptionContext.cs | 2 +- .../Masa.Contrib.Exceptions/_Imports.cs | 2 +- .../ApplicationBuilderExtensions.cs | 2 +- ...trib.Globalization.I18n.AspNetCore.csproj} | 2 +- .../README.md | 28 +++---- .../README.zh-CN.md | 28 +++---- .../_Imports.cs | 2 +- .../DccI18nResourceContributor.cs} | 6 +- .../DccResource.cs | 2 +- .../Extensions/I18nOptionsExtensions.cs} | 18 ++--- .../Extensions/I18nResourceExtensions.cs} | 14 ++-- .../Internal/Constant.cs | 2 +- ...asa.Contrib.Globalization.I18n.Dcc.csproj} | 2 +- .../_Imports.cs | 5 +- .../Constant.cs | 4 +- .../EmbeddedResourceUtils.cs | 2 +- .../Extensions/I18nResourceExtensions.cs} | 18 ++--- .../Extensions/ServiceCollectionExtensions.cs | 78 +++++++++---------- .../FileConfigurationProvider.cs | 4 +- .../Internal/CultureUtils.cs | 2 +- .../Internal/PathUtils.cs | 4 +- .../Json/JsonConfigurationProvider.cs | 2 +- .../JsonConfigurationProviderByEmbedded.cs | 4 +- .../Json/JsonConfigurationSource.cs | 2 +- .../Json/JsonConfigurationSourceByEmbedded.cs | 2 +- .../LocalI18nResourceContributor.cs} | 6 +- .../Masa.Contrib.Globalization.I18n.csproj} | 6 +- .../README.md | 26 +++---- .../README.zh-CN.md | 26 +++---- .../I18n}/Framework/Languages/en-US.json | 0 .../I18n}/Framework/Languages/zh-CN.json | 0 .../Framework/ParameterValidations/en-US.json | 0 .../Framework/ParameterValidations/zh-CN.json | 0 .../Resources/I18n}/Framework/en-US.json | 0 .../Resources/I18n}/Framework/zh-CN.json | 0 .../_Imports.cs | 12 +-- .../I18nTest.cs} | 18 ++--- ...ntrib.Globalization.I18n.Dcc.Tests.csproj} | 10 +-- .../Resources/I18n}/en-US.json | 0 .../Resources/I18n}/supportedCultures.json | 0 .../Resources/I18n}/zh-CN.json | 0 .../_Imports.cs | 2 +- .../I18nTest.cs | 44 +++++------ ...a.Contrib.Globalization.I18n.Tests.csproj} | 5 +- .../Resources/I18n}/en-US.json | 0 .../Resources/I18n}/supportedCultures.json | 0 .../Resources/I18n}/zh-CN.json | 0 .../_Imports.cs | 2 +- 81 files changed, 321 insertions(+), 324 deletions(-) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Constant.cs (63%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/CultureModel.cs (90%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/CultureSettings.cs (92%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/DefaultLanguageProvider.cs (80%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/I18N.cs => Masa.BuildingBlocks.Globalization.I18n/I18n.cs} (84%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/I18nOfT.cs (84%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs => Masa.BuildingBlocks.Globalization.I18n/I18nResource.cs} (81%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs => Masa.BuildingBlocks.Globalization.I18n/I18nResourceDictionary.cs} (58%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs => Masa.BuildingBlocks.Globalization.I18n/I18nResourceResourceConfiguration.cs} (60%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/II18N.cs => Masa.BuildingBlocks.Globalization.I18n/II18n.cs} (98%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs => Masa.BuildingBlocks.Globalization.I18n/II18nOfT.cs} (60%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs => Masa.BuildingBlocks.Globalization.I18n/II18nResourceContributor.cs} (70%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/ILanguageProvider.cs (82%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/InheritResourceAttribute.cs (88%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/LanguageInfo.cs (93%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj => Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj} (100%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs => Masa.BuildingBlocks.Globalization.I18n/Options/I18nOptions.cs} (75%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs => Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18nOptions.cs} (59%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/DefaultResource.cs (84%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/MasaFrameworkResource.cs (88%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/MasaLanguageResource.cs (82%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/Resources/MasaParameterValidationResource.cs (86%) rename src/BuildingBlocks/Globalization/{Masa.BuildingBlocks.Globalization.I18N => Masa.BuildingBlocks.Globalization.I18n}/_Imports.cs (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/Extensions/ApplicationBuilderExtensions.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj => Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj} (89%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/README.md (71%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/README.zh-CN.md (66%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.AspNetCore => Masa.Contrib.Globalization.I18n.AspNetCore}/_Imports.cs (84%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs => Masa.Contrib.Globalization.I18n.Dcc/DccI18nResourceContributor.cs} (83%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/DccResource.cs (79%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs => Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nOptionsExtensions.cs} (57%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs => Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nResourceExtensions.cs} (67%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/Internal/Constant.cs (81%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj => Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj} (91%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N.Dcc => Masa.Contrib.Globalization.I18n.Dcc}/_Imports.cs (70%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Constant.cs (89%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/EmbeddedResourceUtils.cs (97%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs => Masa.Contrib.Globalization.I18n/Extensions/I18nResourceExtensions.cs} (93%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Extensions/ServiceCollectionExtensions.cs (66%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/FileConfigurationProvider.cs (96%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Internal/CultureUtils.cs (95%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Internal/PathUtils.cs (81%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationProvider.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationProviderByEmbedded.cs (95%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationSource.cs (95%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/Json/JsonConfigurationSourceByEmbedded.cs (94%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs => Masa.Contrib.Globalization.I18n/LocalI18nResourceContributor.cs} (87%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj => Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj} (79%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/README.md (83%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/README.zh-CN.md (82%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Resources/I18N => Masa.Contrib.Globalization.I18n/Resources/I18n}/Framework/Languages/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Resources/I18N => Masa.Contrib.Globalization.I18n/Resources/I18n}/Framework/Languages/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Resources/I18N => Masa.Contrib.Globalization.I18n/Resources/I18n}/Framework/ParameterValidations/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Resources/I18N => Masa.Contrib.Globalization.I18n/Resources/I18n}/Framework/ParameterValidations/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Resources/I18N => Masa.Contrib.Globalization.I18n/Resources/I18n}/Framework/en-US.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N/Resources/I18N => Masa.Contrib.Globalization.I18n/Resources/I18n}/Framework/zh-CN.json (100%) rename src/Contrib/Globalization/{Masa.Contrib.Globalization.I18N => Masa.Contrib.Globalization.I18n}/_Imports.cs (68%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs => Masa.Contrib.Globalization.I18n.Dcc.Tests/I18nTest.cs} (78%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj => Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj} (77%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N => Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n}/en-US.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N => Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n}/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N => Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n}/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Dcc.Tests => Masa.Contrib.Globalization.I18n.Dcc.Tests}/_Imports.cs (88%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests => Masa.Contrib.Globalization.I18n.Tests}/I18nTest.cs (61%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj => Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj} (90%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests/Resources/I18N => Masa.Contrib.Globalization.I18n.Tests/Resources/I18n}/en-US.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests/Resources/I18N => Masa.Contrib.Globalization.I18n.Tests/Resources/I18n}/supportedCultures.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests/Resources/I18N => Masa.Contrib.Globalization.I18n.Tests/Resources/I18n}/zh-CN.json (100%) rename src/Contrib/Globalization/Tests/{Masa.Contrib.Globalization.I18N.Tests => Masa.Contrib.Globalization.I18n.Tests}/_Imports.cs (85%) diff --git a/Masa.Framework.sln b/Masa.Framework.sln index 4c00251d0..aadb4b9e3 100644 --- a/Masa.Framework.sln +++ b/Masa.Framework.sln @@ -597,15 +597,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.Da EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Development.DaprStarter.AspNetCore.Tests", "src\Contrib\Development\Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests\Masa.Contrib.Development.DaprStarter.AspNetCore.Tests.csproj", "{DD899DC4-A2B7-4C7B-A644-EDB56A61145C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N\Masa.Contrib.Globalization.I18N.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n\Masa.Contrib.Globalization.I18n.csproj", "{F9E3EBD9-EE96-40F7-BDC7-818B88557D6B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D2E598D5-5E44-4275-AF03-4BAD07A0E13B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Tests\Masa.Contrib.Globalization.I18N.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18n.Tests\Masa.Contrib.Globalization.I18n.Tests.csproj", "{6C732EBE-22CC-4160-B427-F4558C899024}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.Dcc\Masa.Contrib.Globalization.I18N.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Dcc", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n.Dcc\Masa.Contrib.Globalization.I18n.Dcc.csproj", "{B0EFDF9E-81FF-4880-992B-8A65A2008717}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests\Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.Dcc.Tests", "src\Contrib\Globalization\Tests\Masa.Contrib.Globalization.I18n.Dcc.Tests\Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj", "{91FE0D47-D6DB-4D2D-8C6F-15FCE974AB52}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exception", "Exception", "{84F366D3-6E9A-4101-AEC0-287CBA6984A8}" EndProject @@ -617,11 +617,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Exceptions", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.Exceptions.Tests", "src\BuildingBlocks\Exception\Masa.BuildingBlocks.Exceptions.Tests\Masa.BuildingBlocks.Exceptions.Tests.csproj", "{921DCAAC-3146-4EDB-891C-D76089E4A451}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18N.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18N.AspNetCore\Masa.Contrib.Globalization.I18N.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Globalization.I18n.AspNetCore", "src\Contrib\Globalization\Masa.Contrib.Globalization.I18n.AspNetCore\Masa.Contrib.Globalization.I18n.AspNetCore.csproj", "{B7AEC624-6A40-42E7-BDB5-4487ACE48CE4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Dispatcher.Events.FluentValidation", "src\Contrib\Dispatcher\Masa.Contrib.Dispatcher.Events.FluentValidation\Masa.Contrib.Dispatcher.Events.FluentValidation.csproj", "{66B1723A-D578-418C-B21C-2C3B5CBD1180}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.I18N", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18N\Masa.BuildingBlocks.Globalization.I18N.csproj", "{6088C3D3-E17E-41BC-A21F-F222F5123DF1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Globalization.I18n", "src\BuildingBlocks\Globalization\Masa.BuildingBlocks.Globalization.I18n\Masa.BuildingBlocks.Globalization.I18n.csproj", "{6088C3D3-E17E-41BC-A21F-F222F5123DF1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs index 135f9df5a..86cbd151d 100644 --- a/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs +++ b/src/BuildingBlocks/Data/Masa.BuildingBlocks.Data/Constants/ErrorCode.cs @@ -12,7 +12,7 @@ public static class ErrorCode /// /// Internal service error /// - private const string INTERNAL_SERVER = $"{FRAMEWORK_PREFIX}Ser"; + private const string INTERNAL_SERVER = $"{FRAMEWORK_PREFIX}SVR"; /// /// parameter validation error @@ -140,19 +140,20 @@ public static class ErrorCode /// /// '{PropertyName}' must not be more than {ExpectedPrecision} digits in total, with allowance for {ExpectedScale} decimals. {Digits} digits and {ActualScale} decimals were found. /// - [Description( - "'{0}' must not be more than {1} digits in total, with allowance for {2} decimals. {3} digits and {4} decimals were found.")] + [Description("'{0}' must not be more than {1} digits in total, with allowance for {2} decimals. {3} digits and {4} decimals were found.")] public const string SCALE_PRECISION_VALIDATOR = $"{ARGUMENT}0020"; /// /// '{PropertyName}' must be empty. /// - [Description("'{0}' must be empty.")] public const string EMPTY_VALIDATOR = $"{ARGUMENT}0021"; + [Description("'{0}' must be empty.")] + public const string EMPTY_VALIDATOR = $"{ARGUMENT}0021"; /// /// '{PropertyName}' must be empty. /// - [Description("'{0}' must be empty.")] public const string NULL_VALIDATOR = $"{ARGUMENT}0022"; + [Description("'{0}' must be empty.")] + public const string NULL_VALIDATOR = $"{ARGUMENT}0022"; /// /// '{0}' has a range of values which does not include '{1}'. diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj index af9c871f2..63c029362 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/Masa.BuildingBlocks.Exceptions.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs index edef2c0d6..849480604 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaException.cs @@ -15,7 +15,7 @@ public class MasaException : Exception public string? ErrorCode => _errorCode; /// - /// Provides error message that I18N is not used + /// Provides error message that I18n is not used /// protected string? ErrorMessage { get; set; } @@ -25,36 +25,36 @@ public class MasaException : Exception private bool _initialize; - private II18N? _i18N; + private II18n? _i18n; - internal II18N? I18N + internal II18n? I18n { get { TryInitialize(); - return _i18N; + return _i18n; } } - private II18N? _frameworkI18N; + private II18n? _frameworkI18n; - internal II18N? FrameworkI18N + internal II18n? FrameworkI18n { get { TryInitialize(); - return _frameworkI18N; + return _frameworkI18n; } } - private bool _supportI18N; + private bool _supportI18n; - internal bool SupportI18N + internal bool SupportI18n { get { TryInitialize(); - return _supportI18N; + return _supportI18n; } } @@ -68,9 +68,9 @@ private void TryInitialize() private void Initialize() { - _frameworkI18N = MasaApp.GetService>(); - _i18N = MasaApp.GetService>(); - _supportI18N = _frameworkI18N != null; + _frameworkI18n = MasaApp.GetService>(); + _i18n = MasaApp.GetService>(); + _supportI18n = _frameworkI18n != null; _initialize = true; } @@ -118,7 +118,7 @@ public string GetLocalizedMessage() protected virtual string GetLocalizedMessageExecuting() { - if (!SupportI18N) + if (!SupportI18n) { if (string.IsNullOrWhiteSpace(ErrorMessage)) return Message; @@ -129,10 +129,10 @@ protected virtual string GetLocalizedMessageExecuting() if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) { //The current framework frame exception - return FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; + return FrameworkI18n!.T(ErrorCode!, false, GetParameters()) ?? Message; } - return I18N!.T(ErrorCode, false, GetParameters()) ?? Message; + return I18n!.T(ErrorCode, false, GetParameters()) ?? Message; } protected virtual object[] GetParameters() => Parameters; diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs index d9df2d6c7..3aaed325d 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/MasaValidatorException.cs @@ -207,7 +207,7 @@ private static void Throw( protected override string GetLocalizedMessageExecuting() { string message; - if (!SupportI18N) + if (!SupportI18n) { message = string.IsNullOrWhiteSpace(ErrorMessage) ? Message : string.Format(ErrorMessage, GetParameters()); } @@ -215,11 +215,11 @@ protected override string GetLocalizedMessageExecuting() else if (ErrorCode!.StartsWith(Masa.BuildingBlocks.Data.Constants.ErrorCode.FRAMEWORK_PREFIX)) { //The current framework frame exception - message = FrameworkI18N!.T(ErrorCode!, false, GetParameters()) ?? Message; + message = FrameworkI18n!.T(ErrorCode!, false, GetParameters()) ?? Message; } else { - message = I18N!.T(ErrorCode, false, GetParameters()) ?? Message; + message = I18n!.T(ErrorCode, false, GetParameters()) ?? Message; } return FormatMessage(new ValidationModel(ParamName!, message)); diff --git a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs index b8c377e57..fc7a5860b 100644 --- a/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs +++ b/src/BuildingBlocks/Exception/Masa.BuildingBlocks.Exceptions/_Imports.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Globalization.I18n; global using Microsoft.Extensions.Logging; global using System.Diagnostics.CodeAnalysis; global using System.Runtime.CompilerServices; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Constant.cs similarity index 63% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Constant.cs index 4eb65631d..6d3df15d9 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Constant.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Constant.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; public static class Constant { - public const string DEFAULT_LOCAL_SECTION = "I18N"; + public const string DEFAULT_LOCAL_SECTION = "I18n"; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureModel.cs similarity index 90% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureModel.cs index 6c6bba727..b2f22cf90 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureModel.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureModel.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; public class CultureModel { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureSettings.cs similarity index 92% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureSettings.cs index 7ed76b36f..9e5627bea 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/CultureSettings.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/CultureSettings.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; public class CultureSettings { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs similarity index 80% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs index 941efa794..03e41063a 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/DefaultLanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/DefaultLanguageProvider.cs @@ -1,11 +1,11 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; public class DefaultLanguageProvider : ILanguageProvider { - private readonly II18N _i18N; + private readonly II18n _i18n; private readonly IOptions _options; private static readonly Dictionary _languages = new() @@ -14,22 +14,22 @@ public class DefaultLanguageProvider : ILanguageProvider { "zh-CN", "中文 (简体)" } }; - public DefaultLanguageProvider(II18N i18N, IOptions options) + public DefaultLanguageProvider(II18n i18n, IOptions options) { - _i18N = i18N; + _i18n = i18n; _options = options; } public IReadOnlyList GetLanguages() { var list = new List(); - string cultureName = _i18N.GetCultureInfo().Name; + string cultureName = _i18n.GetCultureInfo().Name; _options.Value.SupportedCultures.ForEach(culture => { string key = culture.Culture.Equals(cultureName, StringComparison.OrdinalIgnoreCase) ? nameof(LanguageInfo.UIDisplayName) : $"{culture.Culture}\\.{nameof(LanguageInfo.UIDisplayName)}"; - var uiDisplayName = _i18N.T(key); + var uiDisplayName = _i18n.T(key); var languageInfo = new LanguageInfo(culture.Culture, culture.DisplayName ?? GetDisplayName(cultureName), culture.Icon) { UIDisplayName = uiDisplayName diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18n.cs similarity index 84% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18n.cs index 254effc2a..91f5d16ad 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18n.cs @@ -1,15 +1,15 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public static class I18N +public static class I18n { private static readonly IServiceProvider _serviceProvider = MasaApp.RootServiceProvider; - private static readonly II18N _i18N = InitI18N(); + private static readonly II18n _i18n = InitI18n(); private static readonly ILanguageProvider _languageProvider = InitLanguage(); - static II18N InitI18N() => _serviceProvider.GetRequiredService(); + static II18n InitI18n() => _serviceProvider.GetRequiredService(); static ILanguageProvider InitLanguage() => _serviceProvider.GetRequiredService(); @@ -18,7 +18,7 @@ public static class I18N /// /// The name of the string resource. /// - public static string T(string name) => _i18N.T(name); + public static string T(string name) => _i18n.T(name); /// /// Gets the string resource with the given name. @@ -26,14 +26,14 @@ public static class I18N /// The name of the string resource. /// Return Key when key does not exist, default: true /// - public static string? T(string name, bool returnKey) => _i18N.T(name, returnKey); + public static string? T(string name, bool returnKey) => _i18n.T(name, returnKey); /// /// Gets the string resource with the given name and formatted with the supplied arguments. /// /// The name of the string resource. /// The values to format the string with. - public static string T(string name, params object[] arguments) => _i18N.T(name, arguments); + public static string T(string name, params object[] arguments) => _i18n.T(name, arguments); /// /// Gets the string resource with the given name and formatted with the supplied arguments. @@ -41,9 +41,9 @@ public static class I18N /// The name of the string resource. /// Return Key when key does not exist, default: true /// The values to format the string with. - public static string? T(string name, bool returnKey, params object[] arguments) => _i18N.T(name, returnKey, arguments); + public static string? T(string name, bool returnKey, params object[] arguments) => _i18n.T(name, returnKey, arguments); - public static CultureInfo GetCultureInfo() => _i18N.GetCultureInfo(); + public static CultureInfo GetCultureInfo() => _i18n.GetCultureInfo(); /// /// Set the CultureName @@ -51,20 +51,20 @@ public static class I18N /// /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). - public static void SetCulture(string cultureName, bool useUserOverride = true) => _i18N.SetCulture(cultureName, useUserOverride); + public static void SetCulture(string cultureName, bool useUserOverride = true) => _i18n.SetCulture(cultureName, useUserOverride); /// /// Set the CultureName /// Data used to define "regional options", standards, formats, etc /// /// - public static void SetCulture(CultureInfo culture) => _i18N.SetCulture(culture); + public static void SetCulture(CultureInfo culture) => _i18n.SetCulture(culture); /// /// get interface language /// /// - public static CultureInfo GetUiCultureInfo() => _i18N.GetUiCultureInfo(); + public static CultureInfo GetUiCultureInfo() => _i18n.GetUiCultureInfo(); /// /// Set the CultureName for the current request @@ -72,14 +72,14 @@ public static class I18N /// /// A predefined name, of an existing , or Windows-only culture name. is not case-sensitive. /// A Boolean that denotes whether to use the user-selected culture settings () or the default culture settings (). - public static void SetUiCulture(string cultureName, bool useUserOverride = true) => _i18N.SetUiCulture(cultureName, useUserOverride); + public static void SetUiCulture(string cultureName, bool useUserOverride = true) => _i18n.SetUiCulture(cultureName, useUserOverride); /// /// Set the CultureName for the current request /// Used to set the interface language /// /// - public static void SetUiCulture(CultureInfo culture) => _i18N.SetUiCulture(culture); + public static void SetUiCulture(CultureInfo culture) => _i18n.SetUiCulture(culture); public static IReadOnlyList GetLanguages() => _languageProvider.GetLanguages(); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs similarity index 84% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs index b760b994f..67dcb15b8 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18nOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nOfT.cs @@ -1,12 +1,12 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public class I18N : II18N +public class I18n : II18n { - private readonly I18NResource? _resource; - private readonly List _baseResources; + private readonly I18nResource? _resource; + private readonly List _baseResources; public string this[string name] => T(name); @@ -16,13 +16,13 @@ public class I18N : II18N public string? this[string name, bool returnKey, params object[] arguments] => T(name, returnKey, arguments); - public I18N() + public I18n() { - _resource = I18NResourceResourceConfiguration.Resources.GetOrNull(); + _resource = I18nResourceResourceConfiguration.Resources.GetOrNull(); _baseResources = _resource?.BaseResourceTypes - .Select(resourceType => I18NResourceResourceConfiguration.Resources.GetOrNull(resourceType)) - .ToList() ?? new List(); + .Select(resourceType => I18nResourceResourceConfiguration.Resources.GetOrNull(resourceType)) + .ToList() ?? new List(); } public string T(string name) => T(name, true)!; @@ -77,12 +77,12 @@ public string T(string name, params object[] arguments) public string? GetOrNull(string name) => GetOrNull(_resource, name); - public string? GetOrNull(I18NResource? i18NResource, string name) + public string? GetOrNull(I18nResource? i18nResource, string name) { - if (i18NResource == null) + if (i18nResource == null) return null; - var resourceContributor = i18NResource.GetResourceContributor(GetUiCultureInfo()); + var resourceContributor = i18nResource.GetResourceContributor(GetUiCultureInfo()); return resourceContributor?.GetOrNull(name); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResource.cs similarity index 81% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResource.cs index 5efdc7572..233a97e0e 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResource.cs @@ -1,11 +1,11 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public class I18NResource +public class I18nResource { - private readonly Dictionary _dictionary; + private readonly Dictionary _dictionary; public Type ResourceType { get; } @@ -13,14 +13,14 @@ public class I18NResource public IEnumerable Assemblies { get; set; } = new List(); - public I18NResource(Type resourceType, IEnumerable baseResourceTypes) + public I18nResource(Type resourceType, IEnumerable baseResourceTypes) { _dictionary = new(StringComparer.OrdinalIgnoreCase); ResourceType = resourceType; BaseResourceTypes = baseResourceTypes.ToList(); } - public void AddContributor(string cultureName, II18NResourceContributor localizationResourceContributor) + public void AddContributor(string cultureName, II18nResourceContributor localizationResourceContributor) { if (_dictionary.ContainsKey(cultureName)) throw new ArgumentException($"The {cultureName} already exists with {ResourceType.FullName}"); @@ -28,7 +28,7 @@ public void AddContributor(string cultureName, II18NResourceContributor localiza _dictionary.Add(localizationResourceContributor.CultureName, localizationResourceContributor); } - public II18NResourceContributor? GetResourceContributor(CultureInfo? cultureInfo = null) + public II18nResourceContributor? GetResourceContributor(CultureInfo? cultureInfo = null) { var cultureName = cultureInfo?.Name ?? CultureInfo.CurrentUICulture.Name; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResourceDictionary.cs similarity index 58% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResourceDictionary.cs index b86e73543..7d463085e 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceDictionary.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResourceDictionary.cs @@ -1,23 +1,23 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; [Serializable] -public class I18NResourceDictionary : Dictionary +public class I18nResourceDictionary : Dictionary { - public I18NResourceDictionary() + public I18nResourceDictionary() { } - protected I18NResourceDictionary(SerializationInfo info, StreamingContext context) : base(info, context){} + protected I18nResourceDictionary(SerializationInfo info, StreamingContext context) : base(info, context){} - public I18NResource Add(params Type[] baseResourceTypes) + public I18nResource Add(params Type[] baseResourceTypes) { return Add(typeof(TResource), baseResourceTypes); } - public I18NResource Add(Type resourceType, params Type[] baseResourceTypes) + public I18nResource Add(Type resourceType, params Type[] baseResourceTypes) { List types = new List(baseResourceTypes); @@ -27,40 +27,40 @@ public I18NResource Add(Type resourceType, params Type[] baseResourceTypes) types.AddRange(inheritResourceAttribute.ResourceTypes); } - return this[resourceType] = new I18NResource(resourceType, types.Distinct()); + return this[resourceType] = new I18nResource(resourceType, types.Distinct()); } - public bool TryAdd(Action action, params Type[] baseResourceTypes) + public bool TryAdd(Action action, params Type[] baseResourceTypes) { return TryAdd(typeof(TResource), action, baseResourceTypes); } - public bool TryAdd(Type resourceType, Action action, params Type[] baseResourceTypes) + public bool TryAdd(Type resourceType, Action action, params Type[] baseResourceTypes) { if (this.ContainsKey(resourceType)) return false; - var i18NResource = Add(resourceType, baseResourceTypes); - action.Invoke(i18NResource); + var i18nResource = Add(resourceType, baseResourceTypes); + action.Invoke(i18nResource); return true; } - public Task TryAddAsync(Func func, params Type[] baseResourceTypes) + public Task TryAddAsync(Func func, params Type[] baseResourceTypes) { return TryAddAsync(typeof(TResource), func, baseResourceTypes); } - public async Task TryAddAsync(Type resourceType, Func func, params Type[] baseResourceTypes) + public async Task TryAddAsync(Type resourceType, Func func, params Type[] baseResourceTypes) { if (this.ContainsKey(resourceType)) return false; - var i18NResource = Add(resourceType, baseResourceTypes); - await func.Invoke(i18NResource); + var i18nResource = Add(resourceType, baseResourceTypes); + await func.Invoke(i18nResource); return true; } - public I18NResource? GetOrNull(Type resourceType) + public I18nResource? GetOrNull(Type resourceType) { if (!ContainsKey(resourceType)) return null; @@ -68,5 +68,5 @@ public async Task TryAddAsync(Type resourceType, Func return this[resourceType]; } - public I18NResource? GetOrNull() => GetOrNull(typeof(TResource)); + public I18nResource? GetOrNull() => GetOrNull(typeof(TResource)); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResourceResourceConfiguration.cs similarity index 60% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResourceResourceConfiguration.cs index acead8b1b..12caaae7a 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/I18NResourceResourceConfiguration.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/I18nResourceResourceConfiguration.cs @@ -1,11 +1,11 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public static class I18NResourceResourceConfiguration +public static class I18nResourceResourceConfiguration { public static readonly string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; - public static I18NResourceDictionary Resources { get; set; } = new(); + public static I18nResourceDictionary Resources { get; set; } = new(); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18n.cs similarity index 98% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18n.cs index bef8c9a17..2a81c19d7 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18N.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18n.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public interface II18N +public interface II18n { /// /// Gets the string resource with the given name. diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18nOfT.cs similarity index 60% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18nOfT.cs index 0a32bf50c..66511e8e5 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NOfT.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18nOfT.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public interface II18N : II18N +public interface II18n : II18n { } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18nResourceContributor.cs similarity index 70% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18nResourceContributor.cs index 88a700380..317b89537 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/II18NResourceContributor.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/II18nResourceContributor.cs @@ -1,9 +1,9 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public interface II18NResourceContributor +public interface II18nResourceContributor { string CultureName { get; } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/ILanguageProvider.cs similarity index 82% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/ILanguageProvider.cs index 1c0c8d806..b50f27770 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/ILanguageProvider.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/ILanguageProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; public interface ILanguageProvider { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/InheritResourceAttribute.cs similarity index 88% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/InheritResourceAttribute.cs index ec7c987e9..930a490c0 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/InheritResourceAttribute.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/InheritResourceAttribute.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; [AttributeUsage(AttributeTargets.Class)] public class InheritResourceAttribute : Attribute diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/LanguageInfo.cs similarity index 93% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/LanguageInfo.cs index 77a9a5a14..260264ebb 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/LanguageInfo.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/LanguageInfo.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; public class LanguageInfo { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Masa.BuildingBlocks.Globalization.I18N.csproj rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Masa.BuildingBlocks.Globalization.I18n.csproj diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/I18nOptions.cs similarity index 75% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/I18nOptions.cs index 2f3ac6132..cd96c0e18 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/I18NOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/I18nOptions.cs @@ -3,15 +3,15 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public class I18NOptions +public class I18nOptions { public IServiceCollection Services { get; } public List SupportedCultures { get; } - public I18NOptions(IServiceCollection services, List supportedCultures) + public I18nOptions(IServiceCollection services, List supportedCultures) { Services = services; SupportedCultures = supportedCultures; diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18nOptions.cs similarity index 59% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18nOptions.cs index 627fba350..133931742 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Options/MasaI18NOptions.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Options/MasaI18nOptions.cs @@ -3,13 +3,13 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public class MasaI18NOptions +public class MasaI18nOptions { - public I18NResourceDictionary Resources { get; } + public I18nResourceDictionary Resources { get; } - public MasaI18NOptions() + public MasaI18nOptions() { Resources = new(); } diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/DefaultResource.cs similarity index 84% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/DefaultResource.cs index 14eb727ee..d3b5b7eac 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/DefaultResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/DefaultResource.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; [InheritResource(typeof(MasaFrameworkResource))] public class DefaultResource diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaFrameworkResource.cs similarity index 88% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaFrameworkResource.cs index 7a55cc238..42bd4cf56 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaFrameworkResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaFrameworkResource.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; /// /// Framework Multilingual Resources diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs similarity index 82% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs index 67006b40b..142aaba93 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaLanguageResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaLanguageResource.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; public class MasaLanguageResource { diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaParameterValidationResource.cs similarity index 86% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaParameterValidationResource.cs index fba86e0a7..64498f44f 100644 --- a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/Resources/MasaParameterValidationResource.cs +++ b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/Resources/MasaParameterValidationResource.cs @@ -3,7 +3,7 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; /// /// Framework Multilingual Resources diff --git a/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs b/src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/_Imports.cs similarity index 100% rename from src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18N/_Imports.cs rename to src/BuildingBlocks/Globalization/Masa.BuildingBlocks.Globalization.I18n/_Imports.cs diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs index 702030027..d2f2bb05b 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Extensions/ApplicationBuilderExtensions.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Builder; public static class ApplicationBuilderExtensions { /// - /// Use I18N + /// Use I18n /// /// /// @@ -23,7 +23,7 @@ public static IApplicationBuilder UseMasaExceptionHandler( var option = new MasaExceptionHandlerOptions(); exceptionHandlingOptions?.Invoke(option); - app.UseI18N(defaultCulture); + app.UseI18n(defaultCulture); app.UseMiddleware(Options.Create(option)); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs index 2ba24e8f2..b52ea6fcf 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/ExceptionHandlerMiddleware.cs @@ -27,7 +27,7 @@ public ExceptionHandlerMiddleware( public async Task InvokeAsync(HttpContext httpContext, IServiceProvider serviceProvider) { - var frameworkI18N = serviceProvider.GetService>(); + var frameworkI18n = serviceProvider.GetService>(); try { await _next(httpContext); @@ -67,8 +67,8 @@ await httpContext.Response.WriteTextAsync( } else if (_options.CatchAllException) { - string message = frameworkI18N == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : - frameworkI18N[ErrorCode.INTERNAL_SERVER_ERROR]; + string message = frameworkI18n == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : + frameworkI18n[ErrorCode.INTERNAL_SERVER_ERROR]; await httpContext.Response.WriteTextAsync(httpStatusCode, message); } else diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs index 2982136cd..e9dd2a078 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Handlers/MvcGlobalExceptionFilter.cs @@ -15,20 +15,20 @@ public class MvcGlobalExceptionFilter : IExceptionFilter private readonly IMasaExceptionHandler? _masaExceptionHandler; private readonly MasaExceptionHandlerOptions _options; private readonly MasaExceptionLogRelationOptions _logRelationOptions; - private readonly I18N? _frameworkI18N; + private readonly I18n? _frameworkI18n; private readonly ILogger? _logger; public MvcGlobalExceptionFilter(IServiceProvider serviceProvider, IOptions options, IOptions logRelationOptions, - I18N? frameworkI18N = null, + I18n? frameworkI18n = null, ILogger? logger = null) { _serviceProvider = serviceProvider; _options = options.Value; _masaExceptionHandler = serviceProvider.GetMasaExceptionHandler(_options.MasaExceptionHandlerType); _logRelationOptions = logRelationOptions.Value; - _frameworkI18N = frameworkI18N; + _frameworkI18n = frameworkI18n; _logger = logger; } @@ -73,8 +73,8 @@ public void OnException(ExceptionContext context) { context.ExceptionHandled = true; - string message = _frameworkI18N == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : - _frameworkI18N[ErrorCode.INTERNAL_SERVER_ERROR]; + string message = _frameworkI18n == null ? ErrorCode.GetErrorMessage(ErrorCode.INTERNAL_SERVER_ERROR)! : + _frameworkI18n[ErrorCode.INTERNAL_SERVER_ERROR]; context.Result = new DefaultExceptionResult(message, httpStatusCode, masaExceptionContext.ContentType); diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj index 0d5372eb1..bb1f4fc8c 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/Masa.Contrib.Exceptions.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs index 08e9a7eec..22f4cba33 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/MasaExceptionContext.cs @@ -22,7 +22,7 @@ public class MasaExceptionContext public int StatusCode { get; set; } /// - /// Error code to provide support for subsequent I18N + /// Error code to provide support for subsequent I18n /// public string? ErrorCode { get; set; } diff --git a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs index 0dbb56ce4..735a071c2 100644 --- a/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs +++ b/src/Contrib/Exception/Masa.Contrib.Exceptions/_Imports.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Data.Constants; -global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Globalization.I18n; global using Masa.Contrib.Exceptions.Internal; global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index edc1ce186..677420d9b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -10,7 +10,7 @@ public static class ApplicationBuilderExtensions { private static bool _isInitialize; - public static IApplicationBuilder UseI18N(this IApplicationBuilder app, string? defaultCulture = null) + public static IApplicationBuilder UseI18n(this IApplicationBuilder app, string? defaultCulture = null) { if (_isInitialize) return app; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj similarity index 89% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj index 3da5d7f8d..ef26fdad6 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/Masa.Contrib.Globalization.I18N.AspNetCore.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/Masa.Contrib.Globalization.I18n.AspNetCore.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md similarity index 71% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md index 7d164723f..bb745ec80 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.md @@ -1,17 +1,17 @@ [中](README.zh-CN.md) | EN -Provides the ability to parse and obtain Culture, and use it with [I18N](../Masa.Contrib.Globalization.I18N/README.md). Currently, there are three ways to switch languages: +Provides the ability to parse and obtain Culture, and use it with [I18n](../Masa.Contrib.Globalization.I18n/README.md). Currently, there are three ways to switch languages: * URL parameter method: ?culture=en-US, this method has the highest priority, the format is: culture=region code * Cookies method: call L.SetCulture (region code) method to switch * Client browser language automatic matching: If neither of the previous two methods are set, it supports automatic matching according to the client browser language. -## Masa.Contrib.Globalization.I18N.AspNetCore +## Masa.Contrib.Globalization.I18n.AspNetCore Example: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N.AspNetCore +Install-Package Masa.Contrib.Globalization.I18n.AspNetCore ``` ### getting Started @@ -20,7 +20,7 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore ``` structure - Resources - - I18N + - I18n - en-US.json - zh-CN.json - supportedCultures.json @@ -73,26 +73,26 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore ] ``` -2. Register to use I18N, modify `Program.cs` +2. Register to use I18n, modify `Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` -3. Use `Masa.Contrib.Globalization.I18N.AspNetCore` to provide the ability to parse Culture +3. Use `Masa.Contrib.Globalization.I18n.AspNetCore` to provide the ability to parse Culture ``` C# -app.UseI18N(); +app.UseI18n(); ``` -4. How to use I18N +4. How to use I18n -* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) -* Use `I18N` (**I18N** is a static class) +* Get `II18n` from DI (**II18n** is the interface, supports getting from DI) +* Use `I18n` (**I18n** is a static class) -Take `I18N` as an example: +Take `I18n` as an example: ```` C# -var home = I18N.T("Home"); //Get the value of the language corresponding to the key value Home, this method call will return "Home"; -var name = I18N.T("User.Name");//Output: name (support nesting) +var home = I18n.T("Home"); //Get the value of the language corresponding to the key value Home, this method call will return "Home"; +var name = I18n.T("User.Name");//Output: name (support nesting) ```` \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md similarity index 66% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md index 8618289c3..ef54926b6 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/README.zh-CN.md @@ -1,17 +1,17 @@ 中 | [EN](README.md) -提供解析获取Culture的能力,配合[I18N](../Masa.Contrib.Globalization.I18N/README.zh-CN.md)来使用,目前支持三种方式进行切换语言: +提供解析获取Culture的能力,配合[I18n](../Masa.Contrib.Globalization.I18n/README.zh-CN.md)来使用,目前支持三种方式进行切换语言: * URL 参数 方式: ?culture=en-US,此方式优先级最高,格式为:culture=区域码 * Cookies 方式:调用 L.SetCulture(区域码) 方式切换 * 客户端浏览器语言自动匹配:如果前面两种方式都没有设置,支持自动根据客户端浏览器语言进行匹配。 -## Masa.Contrib.Globalization.I18N.AspNetCore +## Masa.Contrib.Globalization.I18n.AspNetCore 用例: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N.AspNetCore +Install-Package Masa.Contrib.Globalization.I18n.AspNetCore ``` ### 入门 @@ -20,7 +20,7 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore ``` structure - Resources - - I18N + - I18n - en-US.json - zh-CN.json - supportedCultures.json @@ -73,26 +73,26 @@ Install-Package Masa.Contrib.Globalization.I18N.AspNetCore ] ``` -2. 注册使用I18N, 修改`Program.cs` +2. 注册使用I18n, 修改`Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` -3. 使用`Masa.Contrib.Globalization.I18N.AspNetCore`提供解析Culture的能力 +3. 使用`Masa.Contrib.Globalization.I18n.AspNetCore`提供解析Culture的能力 ``` C# -app.UseI18N(); +app.UseI18n(); ``` -4. 如何使用I18N +4. 如何使用I18n -* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) -* 使用`I18N` (**I18N**是静态类) +* 从DI获取`II18n` (**II18n**是接口,支持从DI获取) +* 使用`I18n` (**I18n**是静态类) -以`I18N`为例: +以`I18n`为例: ``` C# -var home = I18N.T("Home"); //获取键值Home对应语言的值,此方法调用将返回"首页"; -var name = I18N.T("User.Name");//输出:名称(支持嵌套) +var home = I18n.T("Home"); //获取键值Home对应语言的值,此方法调用将返回"首页"; +var name = I18n.T("User.Name");//输出:名称(支持嵌套) ``` \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/_Imports.cs similarity index 84% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/_Imports.cs index 4a5e9da4e..a0039cc9f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.AspNetCore/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.AspNetCore/_Imports.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Globalization.I18n; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Options; global using System.Diagnostics.CodeAnalysis; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18nResourceContributor.cs similarity index 83% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18nResourceContributor.cs index 9ace601d0..4a34afd19 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccI18NResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccI18nResourceContributor.cs @@ -1,15 +1,15 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc; +namespace Masa.Contrib.Globalization.I18n.Dcc; -public class DccI18NResourceContributor : II18NResourceContributor +public class DccI18nResourceContributor : II18nResourceContributor { private readonly IConfigurationSection _configurationSection; public string CultureName { get; } - public DccI18NResourceContributor( + public DccI18nResourceContributor( string appId, string configObjectPrefix, string cultureName, diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs similarity index 79% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs index 63d098a0a..032c37d79 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/DccResource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/DccResource.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc; +namespace Masa.Contrib.Globalization.I18n.Dcc; public class DccResource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nOptionsExtensions.cs similarity index 57% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nOptionsExtensions.cs index a0c44c66c..b098babf2 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NOptionsExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nOptionsExtensions.cs @@ -3,30 +3,30 @@ // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; -public static class I18NOptionsExtensions +public static class I18nOptionsExtensions { [ExcludeFromCodeCoverage] - public static void UseDcc(this I18NOptions i18NOptions) - => i18NOptions.UseDcc(Dcc.Internal.Constant.CULTURES_NAME_PREFIX); + public static void UseDcc(this I18nOptions i18nOptions) + => i18nOptions.UseDcc(DccConstant.CULTURES_NAME_PREFIX); [ExcludeFromCodeCoverage] public static void UseDcc( - this I18NOptions i18NOptions, + this I18nOptions i18nOptions, string configObjectPrefix) - => i18NOptions.UseDcc(DccConfig.AppId, configObjectPrefix); + => i18nOptions.UseDcc(DccConfig.AppId, configObjectPrefix); public static void UseDcc( - this I18NOptions i18NOptions, + this I18nOptions i18nOptions, string appId, string configObjectPrefix) { - i18NOptions.Services.Configure(options => + i18nOptions.Services.Configure(options => { options.Resources.TryAdd(resource => { - resource.UseDcc(appId, configObjectPrefix, i18NOptions.SupportedCultures); + resource.UseDcc(appId, configObjectPrefix, i18nOptions.SupportedCultures); }); options.Resources.GetOrNull()?.TryAddBaseResourceTypes(); }); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nResourceExtensions.cs similarity index 67% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nResourceExtensions.cs index 5ed6ff206..5ad159c6f 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Extensions/I18nResourceExtensions.cs @@ -3,12 +3,12 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public static class I18NResourceExtensions +public static class I18nResourceExtensions { - public static I18NResource UseDcc( - this I18NResource i18NResource, + public static I18nResource UseDcc( + this I18nResource i18nResource, string appId, string configObjectPrefix, List supportedCultures) @@ -16,11 +16,11 @@ public static I18NResource UseDcc( var serviceProvider = MasaApp.GetServices().BuildServiceProvider(); var masaConfiguration = serviceProvider.GetRequiredService(); var contributors = supportedCultures - .Select(supportedCulture => new DccI18NResourceContributor(appId, configObjectPrefix, supportedCulture.Culture, masaConfiguration)).ToList(); + .Select(supportedCulture => new DccI18nResourceContributor(appId, configObjectPrefix, supportedCulture.Culture, masaConfiguration)).ToList(); foreach (var contributor in contributors) { - i18NResource.AddContributor(contributor.CultureName, contributor); + i18nResource.AddContributor(contributor.CultureName, contributor); } - return i18NResource; + return i18nResource; } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs similarity index 81% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs index 15f510c3b..375837e3e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Internal/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Internal/Constant.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc.Internal; +namespace Masa.Contrib.Globalization.I18n.Dcc.Internal; internal static class Constant { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj similarity index 91% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj index e4d4212da..719e86fcb 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/Masa.Contrib.Globalization.I18N.Dcc.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/Masa.Contrib.Globalization.I18n.Dcc.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs similarity index 70% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs index 6bf9df3d0..28615d06c 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N.Dcc/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n.Dcc/_Imports.cs @@ -3,9 +3,10 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Globalization.I18n; global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; -global using Masa.Contrib.Globalization.I18N.Dcc; +global using Masa.Contrib.Globalization.I18n.Dcc; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using System.Diagnostics.CodeAnalysis; +global using DccConstant = Masa.Contrib.Globalization.I18n.Dcc.Internal.Constant; diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs similarity index 89% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs index f985ac6aa..6a283f0b8 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Constant.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Constant.cs @@ -1,14 +1,14 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; public static class Constant { public const string SUPPORTED_CULTURES_NAME = "supportedCultures.json"; public static readonly string DefaultResourcePath - = Path.Combine("Resources", "I18N"); + = Path.Combine("Resources", "I18n"); internal static readonly string DefaultFrameworkResourcePath = Path.Combine(DefaultResourcePath, "Framework"); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs similarity index 97% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs index b9749378f..0d531fd75 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/EmbeddedResourceUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/EmbeddedResourceUtils.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; public class EmbeddedResourceUtils { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18nResourceExtensions.cs similarity index 93% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18nResourceExtensions.cs index 72400b451..f046152ab 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/I18NResourceExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/I18nResourceExtensions.cs @@ -3,22 +3,22 @@ // ReSharper disable once CheckNamespace -namespace Masa.BuildingBlocks.Globalization.I18N; +namespace Masa.BuildingBlocks.Globalization.I18n; -public static class I18NResourceExtensions +public static class I18nResourceExtensions { private static IConfiguration? _configuration; private static IMasaConfiguration? _masaConfiguration; - public static I18NResource AddJson( - this I18NResource resource, + public static I18nResource AddJson( + this I18nResource resource, string resourcesDirectory, params CultureModel[] supportedCultures) => resource.AddJson(resourcesDirectory, supportedCultures.ToList()); - public static I18NResource AddJson( - this I18NResource resource, + public static I18nResource AddJson( + this I18nResource resource, string resourcesDirectory, IEnumerable supportedCultures) { @@ -36,8 +36,8 @@ public static I18NResource AddJson( return resource; } - private static List GetResourceContributors( - I18NResource resource, + private static List GetResourceContributors( + I18nResource resource, string resourcesDirectory, IEnumerable supportedCultures) { @@ -64,7 +64,7 @@ private static List GetResourceContributors( useMasaConfiguration); _configuration = configuration; - return supportedCultures.Select(supportedCulture => (II18NResourceContributor)new LocalI18NResourceContributor + return supportedCultures.Select(supportedCulture => (II18nResourceContributor)new LocalI18nResourceContributor ( resource.ResourceType, supportedCulture.Culture, diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs similarity index 66% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs index f99dcc8a4..5cfe6b094 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Extensions/ServiceCollectionExtensions.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Extensions/ServiceCollectionExtensions.cs @@ -7,99 +7,99 @@ namespace Microsoft.Extensions.DependencyInjection; public static class ServiceCollectionExtensions { - public static IServiceCollection AddI18N( + public static IServiceCollection AddI18n( this IServiceCollection services, string languageDirectory, string? supportCultureName = null, - Action? action = null) - => services.AddI18NByEmbedded(Array.Empty(), languageDirectory, supportCultureName, action); + Action? action = null) + => services.AddI18nByEmbedded(Array.Empty(), languageDirectory, supportCultureName, action); - public static IServiceCollection AddI18N( + public static IServiceCollection AddI18n( this IServiceCollection services, Action? settingsAction = null, - Action? action = null) - => services.AddI18NByEmbedded(Array.Empty(), settingsAction, action); + Action? action = null) + => services.AddI18nByEmbedded(Array.Empty(), settingsAction, action); - public static IServiceCollection AddI18NByEmbedded( + public static IServiceCollection AddI18nByEmbedded( this IServiceCollection services, IEnumerable assemblies, string languageDirectory, string? supportCultureName = null, - Action? action = null) + Action? action = null) { - return services.AddI18NByEmbedded(assemblies, + return services.AddI18nByEmbedded(assemblies, settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18nConstant.SUPPORTED_CULTURES_NAME : supportCultureName; }, action); } - public static IServiceCollection AddI18NByEmbedded( + public static IServiceCollection AddI18nByEmbedded( this IServiceCollection services, IEnumerable assemblies, Action? settingsAction = null, - Action? action = null) + Action? action = null) { MasaApp.TrySetServiceCollection(services); var cultureSettings = AddAndGetCultureSettings(services, settingsAction); return services - .AddI18NByFramework(cultureSettings) - .AddI18NCore(action, assemblies, cultureSettings); + .AddI18nByFramework(cultureSettings) + .AddI18nCore(action, assemblies, cultureSettings); } - public static IServiceCollection TestAddI18N( + public static IServiceCollection TestAddI18n( this IServiceCollection services, string languageDirectory, string? supportCultureName = null, - Action? action = null) + Action? action = null) { - return services.TestAddI18N(settings => + return services.TestAddI18n(settings => { settings.ResourcesDirectory = languageDirectory; - settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18NConstant.SUPPORTED_CULTURES_NAME : + settings.SupportCultureName = supportCultureName.IsNullOrWhiteSpace() ? ContribI18nConstant.SUPPORTED_CULTURES_NAME : supportCultureName; settings.SupportedCultures = CultureUtils.GetSupportedCultures(settings.ResourcesDirectory, settings.SupportCultureName!); }, action); } - public static IServiceCollection TestAddI18N( + public static IServiceCollection TestAddI18n( this IServiceCollection services, Action? settingsAction = null, - Action? action = null) + Action? action = null) { MasaApp.SetServiceCollection(services); var cultureSettings = AddAndGetCultureSettings(services, settingsAction); return services - .AddI18NByFramework(cultureSettings) - .AddI18NCore(action, Array.Empty(), cultureSettings); + .AddI18nByFramework(cultureSettings) + .AddI18nCore(action, Array.Empty(), cultureSettings); } - private static IServiceCollection AddI18NByFramework(this IServiceCollection services, CultureSettings languageSettings) + private static IServiceCollection AddI18nByFramework(this IServiceCollection services, CultureSettings languageSettings) { - services.Configure(options => + services.Configure(options => { var assembly = typeof(EmbeddedResourceUtils).Assembly; options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18NConstant.DefaultFrameworkResourcePath, + resource.AddJson(ContribI18nConstant.DefaultFrameworkResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18NConstant.DefaultFrameworkParameterValidationResourcePath, + resource.AddJson(ContribI18nConstant.DefaultFrameworkParameterValidationResourcePath, languageSettings.SupportedCultures); }); options.Resources.TryAdd(resource => { resource.Assemblies = new[] { assembly }; - resource.AddJson(ContribI18NConstant.DefaultFrameworkLanguageResourcePath, + resource.AddJson(ContribI18nConstant.DefaultFrameworkLanguageResourcePath, languageSettings.SupportedCultures); }); }); @@ -115,10 +115,10 @@ private static CultureSettings AddAndGetCultureSettings( settingsAction?.Invoke(settings); if (string.IsNullOrWhiteSpace(settings.ResourcesDirectory)) - settings.ResourcesDirectory = ContribI18NConstant.DefaultResourcePath; + settings.ResourcesDirectory = ContribI18nConstant.DefaultResourcePath; if (string.IsNullOrWhiteSpace(settings.SupportCultureName)) - settings.SupportCultureName = ContribI18NConstant.SUPPORTED_CULTURES_NAME; + settings.SupportCultureName = ContribI18nConstant.SUPPORTED_CULTURES_NAME; if (!settings.SupportedCultures.Any()) settings.SupportedCultures = @@ -128,33 +128,33 @@ private static CultureSettings AddAndGetCultureSettings( return serviceProvider.GetRequiredService>().Value; } - private static IServiceCollection AddI18NCore( + private static IServiceCollection AddI18nCore( this IServiceCollection services, - Action? action, + Action? action, IEnumerable assemblies, CultureSettings cultureSettings) where TResource : class { services.AddOptions(); - services.TryAddTransient(typeof(II18N<>), typeof(I18N<>)); + services.TryAddTransient(typeof(II18n<>), typeof(I18n<>)); services.TryAddSingleton(); - services.TryAddTransient(serviceProvider => (II18N)serviceProvider.GetRequiredService>()); + services.TryAddTransient(serviceProvider => (II18n)serviceProvider.GetRequiredService>()); - services.Configure(options => + services.Configure(options => { var localLanguageSettings = cultureSettings; options.Resources.TryAdd(resource => { if (assemblies.Any()) resource.Assemblies = assemblies; - resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18NConstant.DefaultResourcePath, + resource.AddJson(localLanguageSettings.ResourcesDirectory ?? ContribI18nConstant.DefaultResourcePath, localLanguageSettings.SupportedCultures); }); }); - action?.Invoke(new I18NOptions(services, cultureSettings.SupportedCultures)); + action?.Invoke(new I18nOptions(services, cultureSettings.SupportedCultures)); - var i18NOptions = services.BuildServiceProvider().GetRequiredService>(); - foreach (var resource in i18NOptions.Value.Resources) - I18NResourceResourceConfiguration.Resources[resource.Key] = resource.Value; + var i18nOptions = services.BuildServiceProvider().GetRequiredService>(); + foreach (var resource in i18nOptions.Value.Resources) + I18nResourceResourceConfiguration.Resources[resource.Key] = resource.Value; return services; } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs similarity index 96% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs index b16d851a8..6871166ee 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/FileConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/FileConfigurationProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; public abstract class FileConfigurationProvider : ConfigurationProvider { @@ -33,7 +33,7 @@ public override void Load() private string FormatKey(string cultureName) { - string localSection = BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION; + string localSection = BuildingBlocks.Globalization.I18n.Constant.DEFAULT_LOCAL_SECTION; var list = _useMasaConfiguration ? new List { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs index cce4a0b48..581197b6b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/CultureUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/CultureUtils.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Internal; +namespace Masa.Contrib.Globalization.I18n.Internal; internal static class CultureUtils { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs similarity index 81% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs index a1f299af1..0eb66ca72 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Internal/PathUtils.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Internal/PathUtils.cs @@ -3,14 +3,14 @@ // ReSharper disable once CheckNamespace -namespace Masa.Contrib.Globalization.I18N; +namespace Masa.Contrib.Globalization.I18n; internal static class PathUtils { internal static bool ParseResourcesDirectory(ref string resourcesPath) { resourcesPath.CheckIsNullOrWhiteSpace(); - resourcesPath = Path.Combine(I18NResourceResourceConfiguration.BaseDirectory, resourcesPath.TrimStart("/")); + resourcesPath = Path.Combine(I18nResourceResourceConfiguration.BaseDirectory, resourcesPath.TrimStart("/")); return Directory.Exists(resourcesPath); } } diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs index b93501aaa..77c3a5879 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProvider.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationProvider : FileConfigurationProvider { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs index 1c77b93f6..472ceca79 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationProviderByEmbedded.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationProviderByEmbedded.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationProviderByEmbedded : ConfigurationProvider { @@ -37,7 +37,7 @@ public override void Load() private string FormatKey(string cultureName) { - string localSection = BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION; + string localSection = BuildingBlocks.Globalization.I18n.Constant.DEFAULT_LOCAL_SECTION; var list = _useMasaConfiguration ? new List { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs similarity index 95% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs index 2a941b8c0..98430e83e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSource.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSource.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationSource : IConfigurationSource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs similarity index 94% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs index 591189cbe..074e1277b 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Json/JsonConfigurationSourceByEmbedded.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Json/JsonConfigurationSourceByEmbedded.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Json; +namespace Masa.Contrib.Globalization.I18n.Json; public class JsonConfigurationSourceByEmbedded : IConfigurationSource { diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/LocalI18nResourceContributor.cs similarity index 87% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/LocalI18nResourceContributor.cs index b28521d3a..4795367fa 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/LocalI18NResourceContributor.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/LocalI18nResourceContributor.cs @@ -5,7 +5,7 @@ namespace Microsoft.Extensions.Localization; -public class LocalI18NResourceContributor : II18NResourceContributor +public class LocalI18nResourceContributor : II18nResourceContributor { /// /// Random number for handling special keys. @@ -18,7 +18,7 @@ public class LocalI18NResourceContributor : II18NResourceContributor public string CultureName { get; } - public LocalI18NResourceContributor( + public LocalI18nResourceContributor( Type resourceType, string cultureName, IConfiguration configuration) @@ -30,7 +30,7 @@ public LocalI18NResourceContributor( public string? GetOrNull(string name) { - var section = _configuration.GetSection(Masa.BuildingBlocks.Globalization.I18N.Constant.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); + var section = _configuration.GetSection(Masa.BuildingBlocks.Globalization.I18n.Constant.DEFAULT_LOCAL_SECTION)?.GetSection(ResourceType.Name)?.GetSection(CultureName); if (section != null && section.Exists()) { string newName = name.Replace("\\.", _randomNumber).Replace(".", ConfigurationPath.KeyDelimiter).Replace(_randomNumber, "."); diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj similarity index 79% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj index 1d37d8bbe..8bf37049e 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Masa.Contrib.Globalization.I18N.csproj +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Masa.Contrib.Globalization.I18n.csproj @@ -8,7 +8,7 @@ - + @@ -18,8 +18,8 @@ - - + + diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md similarity index 83% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md index 1b9635bfe..c019f0ea2 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.md @@ -2,12 +2,12 @@ Provide [Internationalization](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization) capability -## Masa.Contrib.Globalization.I18N +## Masa.Contrib.Globalization.I18n Example: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N +Install-Package Masa.Contrib.Globalization.I18n ``` ### getting Started @@ -16,7 +16,7 @@ Install-Package Masa.Contrib.Globalization.I18N ``` structure - Resources - - I18N + - I18n - en-US.json - zh-CN.json - supportedCultures.json @@ -69,25 +69,25 @@ Install-Package Masa.Contrib.Globalization.I18N ] ``` -2. Register to use I18N, modify `Program.cs` +2. Register to use I18n, modify `Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` -3. How to use I18N +3. How to use I18n -* Get `II18N` from DI (**II18N** is the interface, supports getting from DI) -* Use `I18N` (**I18N** is a static class) +* Get `II18n` from DI (**II18n** is the interface, supports getting from DI) +* Use `I18n` (**I18n** is a static class) -Take `I18N` as an example: +Take `I18n` as an example: ``` C# -var home = I18N.T("Home");//Get the value of the language corresponding to the key value Home, this method call will return "Home"; -var name = I18N.T("User.Name");//Output: name (support nesting) +var home = I18n.T("Home");//Get the value of the language corresponding to the key value Home, this method call will return "Home"; +var name = I18n.T("User.Name");//Output: name (support nesting) ``` -### Provided by I18N +### Provided by I18n * SetCulture (string cultureName): Switch CurrentCulture to zh-CN, and the format of numbers, dates, etc. will also change after it is changed * SetUiCulture (string cultureName): Switch the interface language (CurrentUICulture) to zh-CN @@ -98,7 +98,7 @@ var name = I18N.T("User.Name");//Output: name (support nesting) * T (string name, bool returnKey): get the value of the parameter 'name' in the current language * returnKey: whether to return the value of the parameter `name` when the parameter 'name' is not configured in the current language * string T(string name, params object[] arguments): Get the value of the parameter 'name' in the current language, and get the final result according to the incoming parameters - * arguments: parameter value, for example: '{0}' must be greater than 18, then I18N.T("Age",18) should be used + * arguments: parameter value, for example: '{0}' must be greater than 18, then I18n.T("Age",18) should be used * If the parameter has a format such as number, date, etc., it will change with the change of CurrentCulture * string T(string name, bool returnKey, params object[] arguments): Get the value of the parameter 'name' in the current language, and get the final result according to the incoming parameters * GetLanguages(): Get all languages supported by the current system \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md similarity index 82% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md index 36d4266b9..70524b95d 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/README.zh-CN.md +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/README.zh-CN.md @@ -2,12 +2,12 @@ 提供[国际化](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization)能力 -## Masa.Contrib.Globalization.I18N +## Masa.Contrib.Globalization.I18n 用例: ``` powershell -Install-Package Masa.Contrib.Globalization.I18N +Install-Package Masa.Contrib.Globalization.I18n ``` ### 入门 @@ -16,7 +16,7 @@ Install-Package Masa.Contrib.Globalization.I18N ``` structure - Resources - - I18N + - I18n - en-US.json - zh-CN.json - supportedCultures.json @@ -69,25 +69,25 @@ Install-Package Masa.Contrib.Globalization.I18N ] ``` -2. 注册使用I18N, 修改`Program.cs` +2. 注册使用I18n, 修改`Program.cs` ``` C# -services.AddI18N(); +services.AddI18n(); ``` -3. 如何使用I18N +3. 如何使用I18n -* 从DI获取`II18N` (**II18N**是接口,支持从DI获取) -* 使用`I18N` (**I18N**是静态类) +* 从DI获取`II18n` (**II18n**是接口,支持从DI获取) +* 使用`I18n` (**I18n**是静态类) -以`I18N`为例: +以`I18n`为例: ``` C# -var home = I18N.T("Home"); //获取键值Home对应语言的值,此方法调用将返回"首页"; -var name = I18N.T("User.Name");//输出:名称(支持嵌套) +var home = I18n.T("Home"); //获取键值Home对应语言的值,此方法调用将返回"首页"; +var name = I18n.T("User.Name");//输出:名称(支持嵌套) ``` -### I18N提供 +### I18n提供 * SetCulture (string cultureName): 将CurrentCulture切换成zh-CN,它更改后数字、日期等表示格式也随之改变 * SetUiCulture (string cultureName): 将界面语言(CurrentUICulture)切换成zh-CN @@ -98,7 +98,7 @@ var name = I18N.T("User.Name");//输出:名称(支持嵌套) * T (string name, bool returnKey): 得到参数'name'在当前语言下的值 * returnKey: 当参数'name'在当前语言下未配置时,是否返回参数`name`的值 * string T(string name, params object[] arguments): 得到参数'name'在当前语言下的值, 并根据传入参数得到最终的结果 - * arguments: 参数值, 例如: '{0}' 必须大于18, 则应该使用 I18N.T("Age",18) + * arguments: 参数值, 例如: '{0}' 必须大于18, 则应该使用 I18n.T("Age",18) * 如果参数存在数字、日期等格式,它将随着CurrentCulture的更改更改变 * string T(string name, bool returnKey, params object[] arguments): 得到参数'name'在当前语言下的值, 并根据传入参数得到最终的结果 * GetLanguages(): 获取当前系统支持的所有语言 \ No newline at end of file diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/Languages/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/Languages/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/ParameterValidations/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/ParameterValidations/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/en-US.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/en-US.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/en-US.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/en-US.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/zh-CN.json b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/Resources/I18N/Framework/zh-CN.json rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/Resources/I18n/Framework/zh-CN.json diff --git a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs similarity index 68% rename from src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs rename to src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs index eaab79eb6..3cfdd90bb 100644 --- a/src/Contrib/Globalization/Masa.Contrib.Globalization.I18N/_Imports.cs +++ b/src/Contrib/Globalization/Masa.Contrib.Globalization.I18n/_Imports.cs @@ -3,10 +3,10 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Globalization.I18N; -global using Masa.Contrib.Globalization.I18N; -global using Masa.Contrib.Globalization.I18N.Internal; -global using Masa.Contrib.Globalization.I18N.Json; +global using Masa.BuildingBlocks.Globalization.I18n; +global using Masa.Contrib.Globalization.I18n; +global using Masa.Contrib.Globalization.I18n.Internal; +global using Masa.Contrib.Globalization.I18n.Json; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.Configuration.Json; global using Microsoft.Extensions.DependencyInjection; @@ -15,5 +15,5 @@ global using Microsoft.Extensions.Options; global using Microsoft.Extensions.Primitives; global using System.Reflection; -global using ContribI18NConstant = Masa.Contrib.Globalization.I18N.Constant; -global using MasaJsonConfigurationSource = Masa.Contrib.Globalization.I18N.Json.JsonConfigurationSource; +global using ContribI18nConstant = Masa.Contrib.Globalization.I18n.Constant; +global using MasaJsonConfigurationSource = Masa.Contrib.Globalization.I18n.Json.JsonConfigurationSource; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18nTest.cs similarity index 78% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18nTest.cs index 599dfd4ef..d9337b8ff 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/I18NTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/I18nTest.cs @@ -1,17 +1,17 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Dcc.Tests; +namespace Masa.Contrib.Globalization.I18n.Dcc.Tests; [TestClass] -public class I18NTest +public class I18nTest { - private const string DEFAULT_RESOURCE = "Resources/I18N"; + private const string DEFAULT_RESOURCE = "Resources/I18n"; [TestInitialize] public void Initialize() { - I18NResourceResourceConfiguration.Resources = new(); + I18nResourceResourceConfiguration.Resources = new(); } [DataTestMethod] @@ -33,17 +33,17 @@ public void Test(string cultureName, string expectedValue) var configuration = configurationBuilder.Build(); masaConfiguration.Setup(config => config.ConfigurationApi.Get(appId)).Returns(configuration); services.AddSingleton(masaConfiguration.Object); - services.AddI18N(options => + services.AddI18n(options => { options.ResourcesDirectory = DEFAULT_RESOURCE; }, options => options.UseDcc(appId, configObjectPrefix)); MasaApp.SetServiceCollection(services); var serviceProvider = services.BuildServiceProvider(); - var i18N = serviceProvider.GetService(); - Assert.IsNotNull(i18N); - i18N.SetUiCulture(cultureName); - var value = i18N.T(key); + var i18n = serviceProvider.GetService(); + Assert.IsNotNull(i18n); + i18n.SetUiCulture(cultureName); + var value = i18n.T(key); Assert.AreEqual(expectedValue, value); } } diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj similarity index 77% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj index ef4a89bde..03500a563 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests.csproj @@ -23,17 +23,11 @@ - + - - Always - - - Always - - + Always diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/Resources/I18N/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/Resources/I18n/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/_Imports.cs similarity index 88% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/_Imports.cs index a2034b139..07dd5f8d3 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Dcc.Tests/_Imports.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Dcc.Tests/_Imports.cs @@ -3,7 +3,7 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Globalization.I18n; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18nTest.cs similarity index 61% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18nTest.cs index 658d09606..3127c0160 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/I18nTest.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/I18nTest.cs @@ -1,17 +1,17 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Globalization.I18N.Tests; +namespace Masa.Contrib.Globalization.I18n.Tests; [TestClass] -public class I18NTest +public class I18nTest { - private const string DEFAULT_RESOURCE = "Resources/I18N"; + private const string DEFAULT_RESOURCE = "Resources/I18n"; [TestInitialize] public void Initialize() { - I18NResourceResourceConfiguration.Resources = new(); + I18nResourceResourceConfiguration.Resources = new(); } [DataTestMethod] @@ -21,15 +21,15 @@ public void TestLocalization(string cultureName, string expectedValue) { var services = new ServiceCollection(); services.AddLogging(); - services.TestAddI18N(); + services.TestAddI18n(); var serviceProvider = services.BuildServiceProvider(); - var i18N = serviceProvider.GetRequiredService(); - i18N.SetUiCulture(cultureName); - var value = i18N["Name"]; + var i18n = serviceProvider.GetRequiredService(); + i18n.SetUiCulture(cultureName); + var value = i18n["Name"]; Assert.AreEqual(expectedValue, value); - value = i18N.T("Name"); + value = i18n.T("Name"); Assert.AreEqual(expectedValue, value); - value = i18N["Name2"]; + value = i18n["Name2"]; Assert.AreEqual("Name2", value); } @@ -39,15 +39,15 @@ public void TestLocalization(string cultureName, string expectedValue) public void TestLocalization2(string cultureName, string expectedValue) { var builder = WebApplication.CreateBuilder(); - builder.Services.TestAddI18N(DEFAULT_RESOURCE); + builder.Services.TestAddI18n(DEFAULT_RESOURCE); var serviceProvider = builder.Services.BuildServiceProvider(); - var i18N = serviceProvider.GetRequiredService(); - i18N.SetUiCulture(cultureName); - var value = i18N["Name"]; + var i18n = serviceProvider.GetRequiredService(); + i18n.SetUiCulture(cultureName); + var value = i18n["Name"]; Assert.AreEqual(expectedValue, value); - value = i18N.T("Name"); + value = i18n.T("Name"); Assert.AreEqual(expectedValue, value); - value = i18N["Name2"]; + value = i18n["Name2"]; Assert.AreEqual("Name2", value); } @@ -56,15 +56,15 @@ public void TestLocalization2(string cultureName, string expectedValue) public void TestLocalization3(string cultureName, string expectedValue) { var builder = WebApplication.CreateBuilder(); - builder.Services.AddI18N(DEFAULT_RESOURCE); + builder.Services.AddI18n(DEFAULT_RESOURCE); var serviceProvider = builder.Services.BuildServiceProvider(); - var i18N = serviceProvider.GetRequiredService(); - i18N.SetUiCulture(cultureName); - var value = i18N["Name"]; + var i18n = serviceProvider.GetRequiredService(); + i18n.SetUiCulture(cultureName); + var value = i18n["Name"]; Assert.AreEqual(expectedValue, value); - value = i18N.T("Name"); + value = i18n.T("Name"); Assert.AreEqual(expectedValue, value); - value = i18N["Name2"]; + value = i18n["Name2"]; Assert.AreEqual("Name2", value); } } diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj similarity index 90% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj index 793a8e58d..7c7c64021 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Masa.Contrib.Globalization.I18N.Tests.csproj +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Masa.Contrib.Globalization.I18n.Tests.csproj @@ -5,6 +5,7 @@ enable false enable + Masa.Contrib.Globalization.I18n.Tests @@ -25,11 +26,11 @@ - + - + Always diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/en-US.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/en-US.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/en-US.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/en-US.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/supportedCultures.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/supportedCultures.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/supportedCultures.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/supportedCultures.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/zh-CN.json b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/zh-CN.json similarity index 100% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/Resources/I18N/zh-CN.json rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/Resources/I18n/zh-CN.json diff --git a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/_Imports.cs similarity index 85% rename from src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs rename to src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/_Imports.cs index de244af28..a05fd1712 100644 --- a/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18N.Tests/_Imports.cs +++ b/src/Contrib/Globalization/Tests/Masa.Contrib.Globalization.I18n.Tests/_Imports.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.BuildingBlocks.Globalization.I18N; +global using Masa.BuildingBlocks.Globalization.I18n; global using Microsoft.AspNetCore.Builder; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.VisualStudio.TestTools.UnitTesting;