diff --git a/Creational/DesignPatterns.Builder.UnitTests/DesignPatterns.Builder.UnitTests.csproj b/Creational/DesignPatterns.Builder.UnitTests/DesignPatterns.Builder.UnitTests.csproj new file mode 100644 index 0000000..17ada84 --- /dev/null +++ b/Creational/DesignPatterns.Builder.UnitTests/DesignPatterns.Builder.UnitTests.csproj @@ -0,0 +1,36 @@ + + + + net8.0 + enable + enable + false + true + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/Creational/DesignPatterns.Builder.UnitTests/EmailBuilderTests.cs b/Creational/DesignPatterns.Builder.UnitTests/EmailBuilderTests.cs new file mode 100644 index 0000000..641b2c2 --- /dev/null +++ b/Creational/DesignPatterns.Builder.UnitTests/EmailBuilderTests.cs @@ -0,0 +1,43 @@ +using FluentAssertions.Execution; +using Shouldly; +using Xunit; + +namespace DesignPatterns.Builder.UnitTests; + +public class EmailBuilderTests +{ + [Fact] + public void Given_WhenConstructEmail_ThenResultAsExpected() + { + const string sender = "sender@example.com"; + const string recipient = "recipient@example.com"; + const string subject = "Test Email"; + const string body = "This is a test email body."; + var attachments = new [] { "file.txt", "image.jpg" }; + + var emailDirector = new EmailDirector(); + + var email = emailDirector.Construct(builder => + { + builder + .SetSender(sender) + .SetRecipient(recipient) + .SetSubject(subject) + .SetBody(body); + + foreach(var attachment in attachments) + { + builder.AddAttachment(attachment); + } + }); + + using (new AssertionScope()) + { + email.Sender.ShouldBe(sender); + email.Recipient.ShouldBe(recipient); + email.Subject.ShouldBe(subject); + email.Body.ShouldBe(body); + email.Attachments.ShouldBe(attachments); + } + } +} diff --git a/Creational/DesignPatterns.Builder/DesignPatterns.Builder.csproj b/Creational/DesignPatterns.Builder/DesignPatterns.Builder.csproj new file mode 100644 index 0000000..2f4fc77 --- /dev/null +++ b/Creational/DesignPatterns.Builder/DesignPatterns.Builder.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/Creational/DesignPatterns.Builder/EmailBuilder.cs b/Creational/DesignPatterns.Builder/EmailBuilder.cs new file mode 100644 index 0000000..b05fa91 --- /dev/null +++ b/Creational/DesignPatterns.Builder/EmailBuilder.cs @@ -0,0 +1,41 @@ +namespace DesignPatterns.Builder; + +public class EmailBuilder : IEmailBuilder +{ + private readonly EmailMessage emailMessage = new(); + + public IEmailBuilder SetSender(string sender) + { + this.emailMessage.Sender = sender; + return this; + } + + public IEmailBuilder SetRecipient(string recipient) + { + this.emailMessage.Recipient = recipient; + return this; + } + + public IEmailBuilder SetSubject(string subject) + { + this.emailMessage.Subject = subject; + return this; + } + + public IEmailBuilder SetBody(string body) + { + this.emailMessage.Body = body; + return this; + } + + public IEmailBuilder AddAttachment(string attachment) + { + this.emailMessage.Attachments.Add(attachment); + return this; + } + + public EmailMessage Build() + { + return this.emailMessage; + } +} diff --git a/Creational/DesignPatterns.Builder/EmailDirector.cs b/Creational/DesignPatterns.Builder/EmailDirector.cs new file mode 100644 index 0000000..7d6409a --- /dev/null +++ b/Creational/DesignPatterns.Builder/EmailDirector.cs @@ -0,0 +1,11 @@ +namespace DesignPatterns.Builder; + +public class EmailDirector +{ + public EmailMessage Construct(Action builderAction) + { + var builder = new EmailBuilder(); + builderAction(builder); + return builder.Build(); + } +} diff --git a/Creational/DesignPatterns.Builder/EmailMessage.cs b/Creational/DesignPatterns.Builder/EmailMessage.cs new file mode 100644 index 0000000..563d024 --- /dev/null +++ b/Creational/DesignPatterns.Builder/EmailMessage.cs @@ -0,0 +1,25 @@ +namespace DesignPatterns.Builder; + +public class EmailMessage +{ + public EmailMessage() + { + this.Attachments = new List(); + } + + public string Sender { get; set; } + public string Recipient { get; set; } + public string Subject { get; set; } + public string Body { get; set; } + public List Attachments { get; set; } + + public void Send() + { + Console.WriteLine("Email sent:"); + Console.WriteLine($"From: {this.Sender}"); + Console.WriteLine($"To: {this.Recipient}"); + Console.WriteLine($"Subject: {this.Subject}"); + Console.WriteLine($"Body: {this.Body}"); + Console.WriteLine($"Attachments: {string.Join(", ", this.Attachments)}"); + } +} diff --git a/Creational/DesignPatterns.Builder/IEmailBuilder.cs b/Creational/DesignPatterns.Builder/IEmailBuilder.cs new file mode 100644 index 0000000..fb20f7f --- /dev/null +++ b/Creational/DesignPatterns.Builder/IEmailBuilder.cs @@ -0,0 +1,11 @@ +namespace DesignPatterns.Builder; + +public interface IEmailBuilder +{ + IEmailBuilder SetSender(string sender); + IEmailBuilder SetRecipient(string recipient); + IEmailBuilder SetSubject(string subject); + IEmailBuilder SetBody(string body); + IEmailBuilder AddAttachment(string attachment); + EmailMessage Build(); +} diff --git a/Creational/DesignPatterns.Builder/Program.cs b/Creational/DesignPatterns.Builder/Program.cs new file mode 100644 index 0000000..a0b9c15 --- /dev/null +++ b/Creational/DesignPatterns.Builder/Program.cs @@ -0,0 +1,18 @@ +using DesignPatterns.Builder; + +var emailDirector = new EmailDirector(); + +var email = emailDirector.Construct(builder => +{ + builder + .SetSender("sender@example.com") + .SetRecipient("recipient@example.com") + .SetSubject("Test Email") + .SetBody("This is a test email body.") + .AddAttachment("file.txt") + .AddAttachment("image.jpg"); +}); + +email.Send(); + +Console.WriteLine(); diff --git a/DesignPatterns.sln b/DesignPatterns.sln index dac61e7..38286f8 100644 --- a/DesignPatterns.sln +++ b/DesignPatterns.sln @@ -26,6 +26,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns.FactoryMetho EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns.Decorator.UnitTests", "Structural\DesignPatterns.Decorator.UnitTests\DesignPatterns.Decorator.UnitTests.csproj", "{3942358E-6D3A-441B-ABD7-7FCB0DF988BD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns.Builder", "Creational\DesignPatterns.Builder\DesignPatterns.Builder.csproj", "{727C96E6-5B0E-43BE-BB4E-2D06F40E51BF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns.Builder.UnitTests", "Creational\DesignPatterns.Builder.UnitTests\DesignPatterns.Builder.UnitTests.csproj", "{774BAD81-C8DA-4491-B53C-F023A8235AA7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -72,6 +76,14 @@ Global {3942358E-6D3A-441B-ABD7-7FCB0DF988BD}.Debug|Any CPU.Build.0 = Debug|Any CPU {3942358E-6D3A-441B-ABD7-7FCB0DF988BD}.Release|Any CPU.ActiveCfg = Release|Any CPU {3942358E-6D3A-441B-ABD7-7FCB0DF988BD}.Release|Any CPU.Build.0 = Release|Any CPU + {727C96E6-5B0E-43BE-BB4E-2D06F40E51BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {727C96E6-5B0E-43BE-BB4E-2D06F40E51BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {727C96E6-5B0E-43BE-BB4E-2D06F40E51BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {727C96E6-5B0E-43BE-BB4E-2D06F40E51BF}.Release|Any CPU.Build.0 = Release|Any CPU + {774BAD81-C8DA-4491-B53C-F023A8235AA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {774BAD81-C8DA-4491-B53C-F023A8235AA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {774BAD81-C8DA-4491-B53C-F023A8235AA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {774BAD81-C8DA-4491-B53C-F023A8235AA7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {DCE06EB6-BAB5-4573-AF67-128DBCCDB90C} = {7FF0E83F-EBEB-4103-BCD1-2F100E82FCD1} @@ -84,5 +96,7 @@ Global {DAE417C1-F239-4514-9689-6466F0B52A99} = {AE005ED4-5F0B-4AF9-81AE-AAE3AD6F8901} {15D20D32-A0CA-4D4B-9E6F-11A8B8AED366} = {AE005ED4-5F0B-4AF9-81AE-AAE3AD6F8901} {3942358E-6D3A-441B-ABD7-7FCB0DF988BD} = {5961ADCC-5FA6-4076-A9F4-C1D3207ABE1A} + {727C96E6-5B0E-43BE-BB4E-2D06F40E51BF} = {AE005ED4-5F0B-4AF9-81AE-AAE3AD6F8901} + {774BAD81-C8DA-4491-B53C-F023A8235AA7} = {AE005ED4-5F0B-4AF9-81AE-AAE3AD6F8901} EndGlobalSection EndGlobal