├── .gitignore ├── LICENSE ├── README.md ├── global.json ├── src ├── DesignPatterns.sln ├── DesignPatterns │ ├── DesignPatterns.csproj │ ├── Facade │ │ ├── FacadeApp.cs │ │ └── NonFacadeApp.cs │ ├── Factory │ │ ├── FactoryApiClient.cs │ │ ├── FactoryOrderSummary.cs │ │ └── OrderSummaryFactory.cs │ ├── Program.cs │ ├── Strategy │ │ ├── ApiClient.cs │ │ ├── IOrderSummaryRequestBuilder.cs │ │ ├── OrderSummary.cs │ │ ├── OrderSummaryJsonRequestBuilder.cs │ │ └── OrderSummaryXmlRequestBuilder.cs │ └── Visitor │ │ └── WikipediaExample.cs └── run.ps1 └── test ├── Listener.sln ├── Listener ├── Controllers │ ├── ListenController.cs │ └── ValuesController.cs ├── Listener.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json └── listen.ps1 /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.*~ 3 | project.lock.json 4 | .DS_Store 5 | *.pyc 6 | nupkg/ 7 | 8 | # Visual Studio Code 9 | .vscode 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.userosscache 15 | *.sln.docstates 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease/ 21 | [Rr]eleases/ 22 | x64/ 23 | x86/ 24 | build/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Oo]ut/ 29 | msbuild.log 30 | msbuild.err 31 | msbuild.wrn 32 | 33 | # Visual Studio 2015 34 | .vs/ 35 | 36 | # Project Specific 37 | tinroll.api/tin.db -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 MorganW09 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DesignPatterns 2 | 3 | A repo to hold examples of different C# design patterns. 4 | 5 | Some of the Design Patterns here use an httpClient to make requests. The test/ folder contains a C# app that will listen and log every request Posted to it. Use the listen.ps1 script to run it. 6 | 7 | # Articles 8 | 9 | - [Strategy Pattern](https://medium.com/p/c-design-patterns-the-strategy-pattern-3337232e4da6?source=email-89d87dcc9e73--writer.postDistributed&sk=28d196b0365dfa9d54073df41de9a07d) 10 | 11 | - [Factory Pattern](https://codeburst.io/c-design-patterns-the-factory-pattern-1909be102af) 12 | 13 | - [Visitor Pattern](https://thesharperdev.com/c-design-patterns-the-visitor-pattern/) 14 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "2.2.300" 4 | } 5 | } -------------------------------------------------------------------------------- /src/DesignPatterns.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns", "DesignPatterns\DesignPatterns.csproj", "{902ABF77-FCE7-459C-BF20-78503DEA1A99}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Debug|x64.ActiveCfg = Debug|Any CPU 24 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Debug|x64.Build.0 = Debug|Any CPU 25 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Debug|x86.ActiveCfg = Debug|Any CPU 26 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Debug|x86.Build.0 = Debug|Any CPU 27 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Release|x64.ActiveCfg = Release|Any CPU 30 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Release|x64.Build.0 = Release|Any CPU 31 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Release|x86.ActiveCfg = Release|Any CPU 32 | {902ABF77-FCE7-459C-BF20-78503DEA1A99}.Release|x86.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /src/DesignPatterns/DesignPatterns.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/DesignPatterns/Facade/FacadeApp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Facade 6 | { 7 | public class FacadeApp 8 | { 9 | public bool IsSystemHealthy() 10 | { 11 | return IsDatabaseAHealthy() 12 | && IsDatabaseBHealthy() 13 | && IsServiceAHealthy() 14 | && IsServiceBHealthy(); 15 | } 16 | 17 | private bool IsDatabaseAHealthy() 18 | { 19 | //perform checks 20 | return true; 21 | } 22 | 23 | private bool IsDatabaseBHealthy() 24 | { 25 | //perform checks 26 | return true; 27 | } 28 | 29 | private bool IsServiceAHealthy() 30 | { 31 | //perform checks 32 | return true; 33 | } 34 | 35 | private bool IsServiceBHealthy() 36 | { 37 | //perform checks 38 | return true; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/DesignPatterns/Facade/NonFacadeApp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Facade 6 | { 7 | public class NonFacadeApp 8 | { 9 | public bool IsDatabaseAHealthy() 10 | { 11 | //perform checks 12 | return true; 13 | } 14 | 15 | public bool IsDatabaseBHealthy() 16 | { 17 | //perform checks 18 | return true; 19 | } 20 | 21 | public bool IsServiceAHealthy() 22 | { 23 | //perform checks 24 | return true; 25 | } 26 | 27 | public bool IsServiceBHealthy() 28 | { 29 | //perform checks 30 | return true; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/DesignPatterns/Factory/FactoryApiClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DesignPatterns.Factory 9 | { 10 | public class FactoryApiClient 11 | { 12 | private static HttpClient client; 13 | private OrderSummaryFactory factory; 14 | 15 | static FactoryApiClient() 16 | { 17 | client = new HttpClient(); 18 | } 19 | 20 | public FactoryApiClient(OrderSummaryFactory factory) 21 | { 22 | this.factory = factory; 23 | } 24 | 25 | public async Task SendOrderSummary(string uri, FactoryOrderSummary orderSummary) 26 | { 27 | var httpContent = factory.BuildContent(orderSummary); 28 | var response = await client.PostAsync(uri, httpContent); 29 | return response.StatusCode; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/DesignPatterns/Factory/FactoryOrderSummary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Factory 6 | { 7 | public class FactoryOrderSummary 8 | { 9 | public int UserId { get; set; } 10 | public int ItemId { get; set; } 11 | public Vendor Vendor { get; set; } 12 | public DateTime PurchaseDate { get; set; } 13 | public string Name { get; set; } 14 | } 15 | 16 | public enum Vendor 17 | { 18 | LawnChairCo, 19 | MagicCubeInc, 20 | BestComputersInc 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DesignPatterns/Factory/OrderSummaryFactory.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Net.Http; 6 | using System.Text; 7 | using System.Xml.Serialization; 8 | 9 | namespace DesignPatterns.Factory 10 | { 11 | public class OrderSummaryFactory 12 | { 13 | private static XmlSerializer serializer; 14 | 15 | static OrderSummaryFactory() 16 | { 17 | var xRoot = new XmlRootAttribute(); 18 | xRoot.ElementName = "FactoryOrderSummary"; 19 | serializer = new XmlSerializer(typeof(FactoryOrderSummary), xRoot); 20 | } 21 | 22 | public HttpContent BuildContent(FactoryOrderSummary orderSummary) 23 | { 24 | if (orderSummary.Vendor == Vendor.LawnChairCo) 25 | { 26 | string orderSummaryString; 27 | using (StringWriter textWriter = new StringWriter()) 28 | { 29 | serializer.Serialize(textWriter, orderSummary); 30 | orderSummaryString = textWriter.ToString(); 31 | } 32 | return new StringContent(orderSummaryString, Encoding.UTF8, "application/xml"); 33 | } 34 | else 35 | { 36 | var orderSummaryString = JsonConvert.SerializeObject(orderSummary); 37 | return new StringContent(orderSummaryString, Encoding.UTF8, "application/json"); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/DesignPatterns/Program.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Facade; 2 | using DesignPatterns.Factory; 3 | using DesignPatterns.Strategy; 4 | using DesignPatterns.Visitor; 5 | using System; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace DesignPatterns 10 | { 11 | class Program 12 | { 13 | private static string listenUrl = "http://localhost:5000/api/listen"; 14 | static async Task Main(string[] args) 15 | { 16 | //await StrategyPattern(); 17 | //await FactoryPattern(); 18 | VisitorPattern(); 19 | 20 | } 21 | 22 | public static async Task StrategyPattern() 23 | { 24 | var xmlBuilder = new OrderSummaryXmlRequestBuilder(); 25 | var jsonBuilder = new OrderSummaryJsonRequestBuilder(); 26 | 27 | var orderSummary = new OrderSummary 28 | { 29 | UserId = 1, 30 | ItemId = 20, 31 | PurchaseDate = DateTime.UtcNow 32 | }; 33 | 34 | var xmlClient = new ApiClient(xmlBuilder); 35 | var xmlResponse = await xmlClient.SendOrderSummary(listenUrl, orderSummary); 36 | Console.WriteLine(xmlResponse); 37 | 38 | var jsonClient = new ApiClient(jsonBuilder); 39 | var jsonResponse = await jsonClient.SendOrderSummary(listenUrl, orderSummary); 40 | Console.WriteLine(jsonResponse); 41 | 42 | } 43 | 44 | public static async Task FactoryPattern() 45 | { 46 | var lawnChairOrderSummary = new FactoryOrderSummary 47 | { 48 | UserId = 1, 49 | ItemId = 20, 50 | Vendor = Vendor.LawnChairCo, 51 | Name = "Good Chair", 52 | PurchaseDate = DateTime.UtcNow 53 | }; 54 | 55 | var jsonOrderSummary = new FactoryOrderSummary 56 | { 57 | UserId = 2, 58 | ItemId = 21, 59 | Vendor = Vendor.BestComputersInc, 60 | Name = "Good Computer", 61 | PurchaseDate = DateTime.UtcNow 62 | }; 63 | 64 | var xmlClient = new FactoryApiClient(new OrderSummaryFactory()); 65 | 66 | await xmlClient.SendOrderSummary(listenUrl, lawnChairOrderSummary); 67 | await xmlClient.SendOrderSummary(listenUrl, jsonOrderSummary); 68 | } 69 | 70 | public static void FacadePattern() 71 | { 72 | //bad way 73 | var nonFacade = new NonFacadeApp(); 74 | var appHealthy = nonFacade.IsDatabaseAHealthy(); 75 | appHealthy = appHealthy && nonFacade.IsDatabaseBHealthy(); 76 | appHealthy = appHealthy && nonFacade.IsServiceAHealthy(); 77 | appHealthy = appHealthy && nonFacade.IsServiceBHealthy(); 78 | 79 | Console.WriteLine($"Is Non Facade App Healthy?: {appHealthy}"); 80 | 81 | 82 | //good way 83 | var facade = new FacadeApp(); 84 | Console.WriteLine($"Is Facade App Healthy?: {facade.IsSystemHealthy()}"); 85 | 86 | } 87 | 88 | public static void VisitorPattern() 89 | { 90 | var wiki = new WikipediaExample(); 91 | wiki.Run(); 92 | Console.ReadKey(); 93 | 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/DesignPatterns/Strategy/ApiClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Xml.Serialization; 9 | 10 | namespace DesignPatterns.Strategy 11 | { 12 | public class ApiClient 13 | { 14 | private static HttpClient client; 15 | readonly IOrderSummaryRequestBuilder orderSummaryRequestBuilder; 16 | 17 | static ApiClient() 18 | { 19 | client = new HttpClient(); 20 | } 21 | 22 | public ApiClient(IOrderSummaryRequestBuilder orderSummaryRequestBuilder) 23 | { 24 | this.orderSummaryRequestBuilder = orderSummaryRequestBuilder; 25 | } 26 | 27 | public async Task SendOrderSummary(string uri, OrderSummary orderSummary) 28 | { 29 | var httpContent = orderSummaryRequestBuilder.Build(orderSummary); 30 | var response = await client.PostAsync(uri, httpContent); 31 | return response.StatusCode; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DesignPatterns/Strategy/IOrderSummaryRequestBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Strategy 7 | { 8 | public interface IOrderSummaryRequestBuilder 9 | { 10 | HttpContent Build(OrderSummary orderSummary); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DesignPatterns/Strategy/OrderSummary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DesignPatterns.Strategy 4 | { 5 | public class OrderSummary 6 | { 7 | public int UserId { get; set; } 8 | public int ItemId { get; set; } 9 | public DateTime PurchaseDate { get; set; } 10 | public string Name { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DesignPatterns/Strategy/OrderSummaryJsonRequestBuilder.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Net.Http; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Strategy 8 | { 9 | public class OrderSummaryJsonRequestBuilder : IOrderSummaryRequestBuilder 10 | { 11 | public HttpContent Build(OrderSummary orderSummary) 12 | { 13 | var orderSummaryString = JsonConvert.SerializeObject(orderSummary); 14 | return new StringContent(orderSummaryString, Encoding.UTF8, "application/json"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DesignPatterns/Strategy/OrderSummaryXmlRequestBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Xml.Serialization; 7 | 8 | namespace DesignPatterns.Strategy 9 | { 10 | public class OrderSummaryXmlRequestBuilder : IOrderSummaryRequestBuilder 11 | { 12 | private static XmlSerializer serializer; 13 | 14 | static OrderSummaryXmlRequestBuilder() 15 | { 16 | var xRoot = new XmlRootAttribute(); 17 | xRoot.ElementName = "OrderSummary"; 18 | serializer = new XmlSerializer(typeof(OrderSummary), xRoot); 19 | } 20 | 21 | public HttpContent Build(OrderSummary orderSummary) 22 | { 23 | string orderSummaryString; 24 | using (StringWriter textWriter = new StringWriter()) 25 | { 26 | serializer.Serialize(textWriter, orderSummary); 27 | orderSummaryString = textWriter.ToString(); 28 | } 29 | 30 | return new StringContent(orderSummaryString, Encoding.UTF8, "application/xml"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/DesignPatterns/Visitor/WikipediaExample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Visitor 6 | { 7 | //https://en.wikipedia.org/wiki/Visitor_pattern#C#_example 8 | public interface IExpressionVisitor 9 | { 10 | void Visit(Literal literal); 11 | void Visit(Addition addition); 12 | void Visit(Subtraction subtraction); 13 | } 14 | 15 | public interface IExpression 16 | { 17 | void Accept(IExpressionVisitor visitor); 18 | } 19 | 20 | public class Literal : IExpression 21 | { 22 | internal double Value { get; set; } 23 | 24 | public Literal(double value) 25 | { 26 | Value = value; 27 | } 28 | 29 | public void Accept(IExpressionVisitor visitor) 30 | { 31 | visitor.Visit(this); 32 | } 33 | } 34 | 35 | public class Addition : IExpression 36 | { 37 | internal IExpression Left { get; set; } 38 | internal IExpression Right { get; set; } 39 | 40 | public Addition(IExpression left, IExpression right) 41 | { 42 | Left = left; 43 | Right = right; 44 | } 45 | 46 | public void Accept(IExpressionVisitor visitor) 47 | { 48 | visitor.Visit(this); 49 | } 50 | } 51 | 52 | public class Subtraction : IExpression 53 | { 54 | internal IExpression Left { get; set; } 55 | internal IExpression Right { get; set; } 56 | 57 | public Subtraction(IExpression left, IExpression right) 58 | { 59 | Left = left; 60 | Right = right; 61 | } 62 | 63 | public void Accept(IExpressionVisitor visitor) 64 | { 65 | visitor.Visit(this); 66 | } 67 | 68 | } 69 | 70 | public class PrefixExpressionPrinter : IExpressionVisitor 71 | { 72 | StringBuilder sb; 73 | 74 | public PrefixExpressionPrinter(StringBuilder sb) 75 | { 76 | this.sb = sb; 77 | } 78 | 79 | public void Visit(Literal literal) 80 | { 81 | sb.Append(literal.Value); 82 | } 83 | 84 | public void Visit(Addition addition) 85 | { 86 | sb.Append("+ "); 87 | addition.Left.Accept(this); 88 | sb.Append(" "); 89 | addition.Right.Accept(this); 90 | } 91 | 92 | public void Visit(Subtraction subtraction) 93 | { 94 | sb.Append("-"); 95 | subtraction.Left.Accept(this); 96 | sb.Append(" "); 97 | subtraction.Right.Accept(this); 98 | } 99 | 100 | } 101 | 102 | public class InfixExpressionPrinter : IExpressionVisitor 103 | { 104 | StringBuilder sb; 105 | 106 | public InfixExpressionPrinter(StringBuilder sb) 107 | { 108 | this.sb = sb; 109 | } 110 | 111 | public void Visit(Literal literal) 112 | { 113 | sb.Append(literal.Value); 114 | } 115 | 116 | public void Visit(Addition addition) 117 | { 118 | sb.Append("("); 119 | addition.Left.Accept(this); 120 | sb.Append("+"); 121 | addition.Right.Accept(this); 122 | sb.Append(")"); 123 | } 124 | 125 | public void Visit(Subtraction subtraction) 126 | { 127 | sb.Append("("); 128 | subtraction.Left.Accept(this); 129 | sb.Append("-"); 130 | subtraction.Right.Accept(this); 131 | sb.Append(")"); 132 | } 133 | } 134 | 135 | public class PostfixExpressionPrinter : IExpressionVisitor 136 | { 137 | StringBuilder sb; 138 | 139 | public PostfixExpressionPrinter(StringBuilder sb) 140 | { 141 | this.sb = sb; 142 | } 143 | 144 | public void Visit(Literal literal) 145 | { 146 | sb.Append(literal.Value); 147 | } 148 | 149 | public void Visit(Addition addition) 150 | { 151 | addition.Left.Accept(this); 152 | sb.Append(" "); 153 | addition.Right.Accept(this); 154 | sb.Append(" +"); 155 | } 156 | 157 | public void Visit(Subtraction subtraction) 158 | { 159 | subtraction.Left.Accept(this); 160 | sb.Append(" "); 161 | subtraction.Right.Accept(this); 162 | sb.Append(" -"); 163 | } 164 | } 165 | 166 | public class WikipediaExample 167 | { 168 | public void Run() 169 | { 170 | var addition1 = new Addition( 171 | new Literal(5.0), new Literal(6.0)); 172 | 173 | var sb = new StringBuilder(); 174 | var expressionPrinter = new InfixExpressionPrinter(sb); 175 | addition1.Accept(expressionPrinter); 176 | Console.WriteLine(sb); 177 | 178 | var complexAddition = new Addition( 179 | new Addition( 180 | new Subtraction( 181 | new Literal(5.0), new Literal(6.0)), 182 | new Literal(20.0)), 183 | new Addition( 184 | new Literal(1.0), new Literal(3.0))); 185 | 186 | sb.Clear(); 187 | complexAddition.Accept(expressionPrinter); 188 | Console.WriteLine(sb); 189 | 190 | sb.Clear(); 191 | var postfixExpressionPrinter = new PostfixExpressionPrinter(sb); 192 | complexAddition.Accept(postfixExpressionPrinter); 193 | Console.WriteLine(sb); 194 | 195 | sb.Clear(); 196 | var prefixExpressionPrinter = new PrefixExpressionPrinter(sb); 197 | complexAddition.Accept(prefixExpressionPrinter); 198 | Console.WriteLine(sb); 199 | } 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /src/run.ps1: -------------------------------------------------------------------------------- 1 | dotnet run --project .\DesignPatterns\DesignPatterns.csproj -------------------------------------------------------------------------------- /test/Listener.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Listener", "Listener\Listener.csproj", "{B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Debug|x64.ActiveCfg = Debug|Any CPU 24 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Debug|x64.Build.0 = Debug|Any CPU 25 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Debug|x86.ActiveCfg = Debug|Any CPU 26 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Debug|x86.Build.0 = Debug|Any CPU 27 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Release|x64.ActiveCfg = Release|Any CPU 30 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Release|x64.Build.0 = Release|Any CPU 31 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Release|x86.ActiveCfg = Release|Any CPU 32 | {B29BFF9C-7A15-4D01-B371-59A15A3FEBD8}.Release|x86.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /test/Listener/Controllers/ListenController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.AspNetCore.Http.Internal; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Newtonsoft.Json.Linq; 11 | 12 | namespace Listener.Controllers 13 | { 14 | [Route("api/[controller]")] 15 | [ApiController] 16 | public class ListenController : ControllerBase 17 | { 18 | 19 | // POST api/listen 20 | [HttpPost] 21 | public void Post() 22 | { 23 | using (StreamReader stream = new StreamReader(HttpContext.Request.Body)) 24 | { 25 | string body = stream.ReadToEnd(); 26 | Console.WriteLine(body); 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /test/Listener/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace Listener.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class ValuesController : ControllerBase 12 | { 13 | // GET api/values 14 | [HttpGet] 15 | public ActionResult> Get() 16 | { 17 | return new string[] { "value1", "value2" }; 18 | } 19 | 20 | // GET api/values/5 21 | [HttpGet("{id}")] 22 | public ActionResult Get(int id) 23 | { 24 | return "value"; 25 | } 26 | 27 | // POST api/values 28 | [HttpPost] 29 | public void Post([FromBody] string value) 30 | { 31 | } 32 | 33 | // PUT api/values/5 34 | [HttpPut("{id}")] 35 | public void Put(int id, [FromBody] string value) 36 | { 37 | } 38 | 39 | // DELETE api/values/5 40 | [HttpDelete("{id}")] 41 | public void Delete(int id) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/Listener/Listener.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/Listener/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace Listener 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/Listener/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:50564", 8 | "sslPort": 44395 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Listener": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /test/Listener/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Logging; 12 | using Microsoft.Extensions.Options; 13 | 14 | namespace Listener 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 29 | } 30 | 31 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 32 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 33 | { 34 | if (env.IsDevelopment()) 35 | { 36 | app.UseDeveloperExceptionPage(); 37 | } 38 | else 39 | { 40 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 41 | app.UseHsts(); 42 | } 43 | 44 | app.UseMvc(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/Listener/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/Listener/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /test/listen.ps1: -------------------------------------------------------------------------------- 1 | dotnet run --project .\Listener\Listener.csproj --------------------------------------------------------------------------------