diff --git a/DesignPatterns.sln b/DesignPatterns.sln index 5bbb0b9..ad127ee 100644 --- a/DesignPatterns.sln +++ b/DesignPatterns.sln @@ -12,6 +12,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns.AbstractFact EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns.AbstractFactory.UnitTests", "Creational\DesignPatterns.AbstractFactory.UnitTests\DesignPatterns.AbstractFactory.UnitTests.csproj", "{1E56CC89-45C1-45F7-9EC8-88D648572816}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Structural", "Structural", "{5961ADCC-5FA6-4076-A9F4-C1D3207ABE1A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns.Decorator", "Structural\DesignPatterns.Decorator\DesignPatterns.Decorator.csproj", "{FA3C4F09-104E-4F7D-9ADB-E7F22917ADF7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -34,11 +38,16 @@ Global {1E56CC89-45C1-45F7-9EC8-88D648572816}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E56CC89-45C1-45F7-9EC8-88D648572816}.Release|Any CPU.ActiveCfg = Release|Any CPU {1E56CC89-45C1-45F7-9EC8-88D648572816}.Release|Any CPU.Build.0 = Release|Any CPU + {FA3C4F09-104E-4F7D-9ADB-E7F22917ADF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA3C4F09-104E-4F7D-9ADB-E7F22917ADF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA3C4F09-104E-4F7D-9ADB-E7F22917ADF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA3C4F09-104E-4F7D-9ADB-E7F22917ADF7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {DCE06EB6-BAB5-4573-AF67-128DBCCDB90C} = {7FF0E83F-EBEB-4103-BCD1-2F100E82FCD1} {02AA0F74-2EFE-4804-8938-A92542860F74} = {7FF0E83F-EBEB-4103-BCD1-2F100E82FCD1} {0C5CFC73-F6E4-4796-A11C-9CA378B80517} = {AE005ED4-5F0B-4AF9-81AE-AAE3AD6F8901} {1E56CC89-45C1-45F7-9EC8-88D648572816} = {AE005ED4-5F0B-4AF9-81AE-AAE3AD6F8901} + {FA3C4F09-104E-4F7D-9ADB-E7F22917ADF7} = {5961ADCC-5FA6-4076-A9F4-C1D3207ABE1A} EndGlobalSection EndGlobal diff --git a/Structural/DesignPatterns.Decorator/CompressionDecorator.cs b/Structural/DesignPatterns.Decorator/CompressionDecorator.cs new file mode 100644 index 0000000..9780e2b --- /dev/null +++ b/Structural/DesignPatterns.Decorator/CompressionDecorator.cs @@ -0,0 +1,18 @@ +namespace DesignPatterns.Decorator; + +internal class CompressionDecorator : UploaderDecorator +{ + public CompressionDecorator(IFileUploader uploader) + : base(uploader) + { + } + + public override async Task Upload(string name, Stream stream) + { + // TODO: add compression logic here. + Console.WriteLine($"{nameof(CompressionDecorator)}.{nameof(Upload)}: started compressing a file..."); + await Task.Delay(1000); + Console.WriteLine($"{nameof(CompressionDecorator)}.{nameof(Upload)}: completed compressing a file."); + await base.Upload(name, stream); + } +} diff --git a/Structural/DesignPatterns.Decorator/DesignPatterns.Decorator.csproj b/Structural/DesignPatterns.Decorator/DesignPatterns.Decorator.csproj new file mode 100644 index 0000000..6e040cb --- /dev/null +++ b/Structural/DesignPatterns.Decorator/DesignPatterns.Decorator.csproj @@ -0,0 +1,11 @@ + + + + Exe + net8.0 + enable + enable + DesignPatterns.Decorator + + + diff --git a/Structural/DesignPatterns.Decorator/EncryptionDecorator.cs b/Structural/DesignPatterns.Decorator/EncryptionDecorator.cs new file mode 100644 index 0000000..24b84ce --- /dev/null +++ b/Structural/DesignPatterns.Decorator/EncryptionDecorator.cs @@ -0,0 +1,18 @@ +namespace DesignPatterns.Decorator; + +internal class EncryptionDecorator : UploaderDecorator +{ + public EncryptionDecorator(IFileUploader uploader) + : base(uploader) + { + } + + public override async Task Upload(string name, Stream stream) + { + // TODO: add encryption logic here. + Console.WriteLine($"{nameof(EncryptionDecorator)}.{nameof(Upload)}: started encrypting a file..."); + await Task.Delay(1000); + Console.WriteLine($"{nameof(EncryptionDecorator)}.{nameof(Upload)}: completed encrypting a file."); + await base.Upload(name, stream); + } +} diff --git a/Structural/DesignPatterns.Decorator/FileUploader.cs b/Structural/DesignPatterns.Decorator/FileUploader.cs new file mode 100644 index 0000000..f34e704 --- /dev/null +++ b/Structural/DesignPatterns.Decorator/FileUploader.cs @@ -0,0 +1,12 @@ +namespace DesignPatterns.Decorator; + +internal class FileUploader : IFileUploader +{ + public async Task Upload(string name, Stream stream) + { + // TODO: add a client to upload files into cloud. + Console.WriteLine($"{nameof(FileUploader)}.{nameof(this.Upload)}: started uploading a file..."); + await Task.Delay(1000); + Console.WriteLine($"{nameof(FileUploader)}.{nameof(this.Upload)}: completed uploading a file."); + } +} diff --git a/Structural/DesignPatterns.Decorator/IFileUploader.cs b/Structural/DesignPatterns.Decorator/IFileUploader.cs new file mode 100644 index 0000000..93838ca --- /dev/null +++ b/Structural/DesignPatterns.Decorator/IFileUploader.cs @@ -0,0 +1,6 @@ +namespace DesignPatterns.Decorator; + +public interface IFileUploader +{ + Task Upload(string name, Stream stream); +} diff --git a/Structural/DesignPatterns.Decorator/Program.cs b/Structural/DesignPatterns.Decorator/Program.cs new file mode 100644 index 0000000..7d9aa91 --- /dev/null +++ b/Structural/DesignPatterns.Decorator/Program.cs @@ -0,0 +1,10 @@ +using DesignPatterns.Decorator; + +IFileUploader fileUploader = new FileUploader(); +fileUploader = new CompressionDecorator(fileUploader); +fileUploader = new EncryptionDecorator(fileUploader); + +await using var stream = new MemoryStream(); +await fileUploader.Upload("file.txt", stream); + +Console.WriteLine(); diff --git a/Structural/DesignPatterns.Decorator/UploaderDecorator.cs b/Structural/DesignPatterns.Decorator/UploaderDecorator.cs new file mode 100644 index 0000000..71ecd95 --- /dev/null +++ b/Structural/DesignPatterns.Decorator/UploaderDecorator.cs @@ -0,0 +1,16 @@ +namespace DesignPatterns.Decorator; + +abstract class UploaderDecorator : IFileUploader +{ + private readonly IFileUploader uploader; + + public UploaderDecorator(IFileUploader uploader) + { + this.uploader = uploader; + } + + public virtual Task Upload(string name, Stream stream) + { + return this.uploader.Upload(name, stream); + } +}