diff --git a/csharp/Platform.Exceptions.Tests/InternationalizationTests.cs b/csharp/Platform.Exceptions.Tests/InternationalizationTests.cs
new file mode 100644
index 0000000..bba09f8
--- /dev/null
+++ b/csharp/Platform.Exceptions.Tests/InternationalizationTests.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Globalization;
+using System.Threading;
+using Xunit;
+
+namespace Platform.Exceptions.Tests
+{
+ ///
+ /// Tests for internationalization functionality.
+ /// Тесты для функциональности интернационализации.
+ ///
+ public class InternationalizationTests
+ {
+ ///
+ /// Tests that exception messages are localized based on the current culture.
+ /// Проверяет, что сообщения исключений локализованы в соответствии с текущей культурой.
+ ///
+ [Fact]
+ public void TestArgumentNullExceptionLocalization()
+ {
+ // Test English (default)
+ Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
+ var englishException = Assert.Throws(() =>
+ Ensure.Always.ArgumentNotNull(null, "testArg"));
+ Assert.Contains("Argument testArg is null", englishException.Message);
+
+ // Test Russian
+ Thread.CurrentThread.CurrentUICulture = new CultureInfo("ru-RU");
+ var russianException = Assert.Throws(() =>
+ Ensure.Always.ArgumentNotNull(null, "testArg"));
+ Assert.Contains("Аргумент testArg равен null", russianException.Message);
+ }
+
+ ///
+ /// Tests that argument criteria exception messages are localized.
+ /// Проверяет, что сообщения исключений критериев аргументов локализованы.
+ ///
+ [Fact]
+ public void TestArgumentCriteriaExceptionLocalization()
+ {
+ // Test English (default)
+ Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
+ var englishException = Assert.Throws(() =>
+ Ensure.Always.ArgumentMeetsCriteria("test", x => x.Length > 10, "shortArg"));
+ Assert.Contains("Argument shortArg does not meet the criteria", englishException.Message);
+
+ // Test Russian
+ Thread.CurrentThread.CurrentUICulture = new CultureInfo("ru-RU");
+ var russianException = Assert.Throws(() =>
+ Ensure.Always.ArgumentMeetsCriteria("test", x => x.Length > 10, "shortArg"));
+ Assert.Contains("Аргумент shortArg не соответствует критерию", russianException.Message);
+ }
+
+ ///
+ /// Tests that exception formatting strings are localized.
+ /// Проверяет, что строки форматирования исключений локализованы.
+ ///
+ [Fact]
+ public void TestExceptionFormattingLocalization()
+ {
+ // Test English (default)
+ Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
+ var innerEx = new InvalidOperationException("Inner");
+ var outerEx = new Exception("Outer", innerEx);
+ var englishFormatted = outerEx.ToStringWithAllInnerExceptions();
+ Assert.Contains("Inner exception:", englishFormatted);
+
+ // Test Russian
+ Thread.CurrentThread.CurrentUICulture = new CultureInfo("ru-RU");
+ var russianFormatted = outerEx.ToStringWithAllInnerExceptions();
+ Assert.Contains("Внутреннее исключение:", russianFormatted);
+ }
+ }
+}
\ No newline at end of file
diff --git a/csharp/Platform.Exceptions/EnsureExtensions.cs b/csharp/Platform.Exceptions/EnsureExtensions.cs
index 83501a6..b5403cf 100644
--- a/csharp/Platform.Exceptions/EnsureExtensions.cs
+++ b/csharp/Platform.Exceptions/EnsureExtensions.cs
@@ -43,7 +43,7 @@ public static void ArgumentNotNull(this EnsureAlwaysExtensionRoot roo
/// The argument.Аргумент.
/// The argument's name.Имя аргумента.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void ArgumentNotNull(this EnsureAlwaysExtensionRoot root, TArgument argument, string argumentName) where TArgument : class => ArgumentNotNull(root, argument, argumentName, $"Argument {argumentName} is null.");
+ public static void ArgumentNotNull(this EnsureAlwaysExtensionRoot root, TArgument argument, string argumentName) where TArgument : class => ArgumentNotNull(root, argument, argumentName, string.Format(Resources.ArgumentIsNull, argumentName));
///
/// Ensures that argument is not null. This check is performed regardless of the build configuration.
@@ -84,7 +84,7 @@ public static void ArgumentMeetsCriteria(this EnsureAlwaysExtensionRo
/// A predicate that determines whether the argument meets a criterion.Предикат определяющий, соответствует ли аргумент критерию.
/// The argument's name.Имя аргумента.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void ArgumentMeetsCriteria(this EnsureAlwaysExtensionRoot root, TArgument argument, Predicate predicate, string argumentName) => ArgumentMeetsCriteria(root, argument, predicate, argumentName, $"Argument {argumentName} does not meet the criteria.");
+ public static void ArgumentMeetsCriteria(this EnsureAlwaysExtensionRoot root, TArgument argument, Predicate predicate, string argumentName) => ArgumentMeetsCriteria(root, argument, predicate, argumentName, string.Format(Resources.ArgumentDoesNotMeetCriteria, argumentName));
///
/// Ensures that the argument meets the criteria. This check is performed regardless of the build configuration.
diff --git a/csharp/Platform.Exceptions/ExceptionExtensions.cs b/csharp/Platform.Exceptions/ExceptionExtensions.cs
index 0694252..a8d1044 100644
--- a/csharp/Platform.Exceptions/ExceptionExtensions.cs
+++ b/csharp/Platform.Exceptions/ExceptionExtensions.cs
@@ -19,7 +19,7 @@ public static class ExceptionExtensions
/// Represents a string returned from in the event of an unsuccessful attempt to format an exception. This field is a constant.
/// Представляет строку выдаваемую из в случае неудачной попытки форматирования исключения. Это поле является константой.
///
- public static readonly string ExceptionStringBuildingFailed = "Unable to format exception.";
+ public static readonly string ExceptionStringBuildingFailed = Resources.UnableToFormatException;
///
/// Ignores the exception, notifying the class about it.
@@ -57,7 +57,7 @@ private static void BuildExceptionString(this StringBuilder sb, Exception except
if (exception.InnerException != null)
{
sb.Indent(level);
- sb.AppendLine("Inner exception: ");
+ sb.AppendLine(Resources.InnerException);
sb.BuildExceptionString(exception.InnerException, level + 1);
}
sb.Indent(level);
diff --git a/csharp/Platform.Exceptions/Platform.Exceptions.csproj b/csharp/Platform.Exceptions/Platform.Exceptions.csproj
index fde4379..2c3b4b7 100644
--- a/csharp/Platform.Exceptions/Platform.Exceptions.csproj
+++ b/csharp/Platform.Exceptions/Platform.Exceptions.csproj
@@ -4,7 +4,7 @@
LinksPlatform's Platform.Exceptions Class Library
Konstantin Diachenko
Platform.Exceptions
- 0.5.0
+ 0.6.0
Konstantin Diachenko
net8
Platform.Exceptions
@@ -23,7 +23,7 @@
true
snupkg
latest
- Update target framework from net7 to net8.
+ Added internationalization support for exception messages. Supports English and Russian languages.
enable
@@ -35,6 +35,22 @@
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+ Resources.resx
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
diff --git a/csharp/Platform.Exceptions/Resources.Designer.cs b/csharp/Platform.Exceptions/Resources.Designer.cs
new file mode 100644
index 0000000..999aad0
--- /dev/null
+++ b/csharp/Platform.Exceptions/Resources.Designer.cs
@@ -0,0 +1,118 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Globalization;
+using System.Resources;
+using System.Runtime.CompilerServices;
+
+namespace Platform.Exceptions
+{
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if (object.ReferenceEquals(resourceMan, null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Platform.Exceptions.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Argument {0} does not meet the criteria..
+ ///
+ internal static string ArgumentDoesNotMeetCriteria
+ {
+ get
+ {
+ return ResourceManager.GetString("ArgumentDoesNotMeetCriteria", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Argument {0} is null..
+ ///
+ internal static string ArgumentIsNull
+ {
+ get
+ {
+ return ResourceManager.GetString("ArgumentIsNull", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Inner exception: .
+ ///
+ internal static string InnerException
+ {
+ get
+ {
+ return ResourceManager.GetString("InnerException", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Unable to format exception..
+ ///
+ internal static string UnableToFormatException
+ {
+ get
+ {
+ return ResourceManager.GetString("UnableToFormatException", resourceCulture);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/csharp/Platform.Exceptions/Resources.resx b/csharp/Platform.Exceptions/Resources.resx
new file mode 100644
index 0000000..4ef3730
--- /dev/null
+++ b/csharp/Platform.Exceptions/Resources.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Argument {0} is null.
+ Message for ArgumentNullException when argument is null
+
+
+ Argument {0} does not meet the criteria.
+ Message for ArgumentException when argument doesn't meet criteria
+
+
+ Unable to format exception.
+ Message when exception formatting fails
+
+
+ Inner exception:
+ Label for inner exception in formatted exception strings
+
+
\ No newline at end of file
diff --git a/csharp/Platform.Exceptions/Resources.ru.resx b/csharp/Platform.Exceptions/Resources.ru.resx
new file mode 100644
index 0000000..fc3b15b
--- /dev/null
+++ b/csharp/Platform.Exceptions/Resources.ru.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Аргумент {0} равен null.
+ Сообщение для ArgumentNullException когда аргумент равен null
+
+
+ Аргумент {0} не соответствует критерию.
+ Сообщение для ArgumentException когда аргумент не соответствует критерию
+
+
+ Невозможно отформатировать исключение.
+ Сообщение когда форматирование исключения не удалось
+
+
+ Внутреннее исключение:
+ Метка для внутреннего исключения в форматированных строках исключений
+
+
\ No newline at end of file