diff --git a/CHANGELOG.md b/CHANGELOG.md
index bde92e1..ca23a68 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,5 +16,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `IServiceCollection` extension methods
- `String` extension methods
- `DateTime` extension methods
+- `StringBuilder` extension methods
- `IFormFile` extension method (AspNetCore package only)
- `DbSet` extension methods for ISortableEntity interface (EntityFrameworkCore package only)
diff --git a/Neolution.Utilities.UnitTests/Extensions/StringBuilderExtensionsTests.cs b/Neolution.Utilities.UnitTests/Extensions/StringBuilderExtensionsTests.cs
new file mode 100644
index 0000000..178f8a2
--- /dev/null
+++ b/Neolution.Utilities.UnitTests/Extensions/StringBuilderExtensionsTests.cs
@@ -0,0 +1,92 @@
+namespace Neolution.Utilities.UnitTests.Extensions;
+
+using System.Text;
+
+///
+/// Unit tests for the class.
+///
+public class StringBuilderExtensionsTests
+{
+ ///
+ /// Test that given the null string builder when AppendLine called then throws argument null exception.
+ ///
+ [Fact]
+ public void GivenNullStringBuilder_WhenAppendLineCalled_ThenThrowsArgumentNullException()
+ {
+ // Arrange
+ StringBuilder? sb = null;
+
+ // Act
+ var act = () => sb!.AppendLine("value", 0);
+
+ // Assert
+ var ex = Should.Throw(act);
+ ex.ParamName.ShouldBe("stringBuilder");
+ }
+
+ ///
+ /// Test that given the negative padding when AppendLine called then throws argument out of range exception.
+ ///
+ [Fact]
+ public void GivenNegativePadding_WhenAppendLineCalled_ThenThrowsArgumentOutOfRangeException()
+ {
+ // Arrange
+ var sb = new StringBuilder();
+
+ // Act
+ var act = () => sb.AppendLine("value", -1);
+
+ // Assert
+ var ex = Should.Throw(act);
+ ex.ParamName.ShouldBe("padding");
+ }
+
+ ///
+ /// Test that given value and padding when AppendLine called then appends expected padded line.
+ ///
+ /// The value.
+ /// The padding.
+ [Theory]
+ [InlineData("Test", 0)]
+ [InlineData("Hello", 4)]
+ [InlineData("", 3)]
+ [InlineData(null, 2)]
+ public void GivenValueAndPadding_WhenAppendLineCalled_ThenAppendsWithPadding(string? value, int padding)
+ {
+ // Arrange
+ var sb = new StringBuilder();
+
+ // Act
+ sb.AppendLine(value, padding);
+
+ // Assert
+ var expected = new string(' ', padding) + (value ?? string.Empty) + Environment.NewLine;
+ sb.ToString().ShouldBe(expected);
+ }
+
+ ///
+ /// Test that given multiple calls when AppendLine called then appends sequentially and returns same instance.
+ ///
+ [Fact]
+ public void GivenMultipleCalls_WhenAppendLineCalled_ThenAppendsSequentiallyAndReturnsSameInstance()
+ {
+ // Arrange
+ var sb = new StringBuilder();
+
+ // Act
+ var returned1 = sb.AppendLine("First", 1);
+ var returned2 = sb.AppendLine("Second", 2);
+ var returned3 = sb.AppendLine(null, 0);
+
+ // Assert
+ returned1.ShouldBeSameAs(sb);
+ returned2.ShouldBeSameAs(sb);
+ returned3.ShouldBeSameAs(sb);
+
+ var expected =
+ " First" + Environment.NewLine +
+ " Second" + Environment.NewLine +
+ Environment.NewLine; // last call: padding 0 + null value => just newline
+ sb.ToString().ShouldBe(expected);
+ }
+}
diff --git a/Neolution.Utilities/Extensions/StringBuilderExtensions.cs b/Neolution.Utilities/Extensions/StringBuilderExtensions.cs
new file mode 100644
index 0000000..da0165c
--- /dev/null
+++ b/Neolution.Utilities/Extensions/StringBuilderExtensions.cs
@@ -0,0 +1,23 @@
+namespace Neolution.Utilities.Extensions;
+
+using System.Text;
+
+///
+/// StringBuilder Extensions
+///
+public static class StringBuilderExtensions
+{
+ ///
+ /// Appends the line with the specified padding
+ ///
+ /// The string builder
+ /// The value
+ /// The padding
+ /// A reference to this instance after the append operation has completed.
+ public static StringBuilder AppendLine(this StringBuilder stringBuilder, string? value, int padding)
+ {
+ ArgumentNullException.ThrowIfNull(stringBuilder);
+ ArgumentOutOfRangeException.ThrowIfNegative(padding);
+ return stringBuilder.Append(' ', padding).AppendLine(value);
+ }
+}