├── --wait
├── .gitattributes
├── .gitignore
├── AbstractFactory
├── AbstractFactory.csproj
├── Cars
│ ├── AbstractCars
│ │ ├── FamilyCar.cs
│ │ └── SportsCar.cs
│ └── ConcreteCars
│ │ ├── AudiFamilyCar.cs
│ │ ├── AudiSportsCar.cs
│ │ ├── MercedesFamilyCar.cs
│ │ └── MercedesSportsCar.cs
├── Client
│ └── Driver.cs
├── Factory
│ ├── AnstractFactory
│ │ └── CarFactory.cs
│ ├── ConcreteFactory
│ │ ├── AudiFactory.cs
│ │ └── MercedesFactory.cs
│ └── GenericFactory.cs
└── Program.cs
├── Adapter
├── Adapted
│ ├── DatabaseHelper.cs
│ ├── WebSiteScanner.cs
│ └── XmlFileLoader.cs
├── Adapter.csproj
├── Adapter
│ ├── Connector.cs
│ ├── DatabaseConnector.cs
│ ├── HttpStreamConnector.cs
│ └── XmlFileConnector.cs
├── Client
│ └── TradingDataImporter.cs
└── Program.cs
├── Bridge
├── Abstraction
│ └── Repository.cs
├── AbstractionRefined
│ ├── ClientRepository.cs
│ └── ProductRepository.cs
├── Bridge.csproj
├── ImplementorAbstract
│ └── DataObject.cs
├── ImplementorConcrete
│ ├── ClientDataObject.cs
│ └── ProductDataObject.cs
└── Program.cs
├── Builder
├── Builder.csproj
├── Builder
│ ├── AbstractBuilder
│ │ └── IPhoneBuilder.cs
│ ├── ConcreteBuilder
│ │ ├── AndroidPhoneBuilder.cs
│ │ └── WindowsPhoneBuilder.cs
│ ├── Director
│ │ └── Manufacturer.cs
│ ├── Object
│ │ └── MobilePhone.cs
│ └── Parts
│ │ ├── BatteryCapacity.cs
│ │ ├── Os.cs
│ │ ├── ScreenType.cs
│ │ └── Stylus.cs
├── FluentBuilder
│ ├── House.cs
│ ├── HouseBuilder.cs
│ └── IHouseBuilder.cs
└── Program.cs
├── CSharpDesignPatterns.sln
├── ChainOfResponsibility
├── Abstrations
│ └── Handler.cs
├── ChainOfResponsibility.csproj
├── Implementations
│ ├── ConcreteHandler1.cs
│ ├── ConcreteHandler2.cs
│ └── ConcreteHandler3.cs
└── Program.cs
├── Command
├── Client
│ └── Program.cs
├── Command.csproj
├── CommandInvoker
│ └── Switch.cs
├── Commands
│ ├── CloseSwitchCommand.cs
│ ├── ICommand.cs
│ └── OpenSwitchCommand.cs
└── Receiver
│ ├── ISwitchable.cs
│ └── Light.cs
├── Composite
├── ComponentObject
│ ├── CompositeGraphic.cs
│ └── IGraphic.cs
├── Composite.csproj
├── LeafObject
│ └── Leaf.cs
└── Program.cs
├── Decorator
├── Component
│ ├── ICoffee.cs
│ └── SimpleCoffee.cs
├── Decorator.csproj
├── Decorator
│ ├── CoffeeDecorator.cs
│ ├── CoffeeWithMilk.cs
│ └── CoffeeWithSprinkles.cs
└── Program.cs
├── Facade
├── CarFacade
│ └── CarFacade.cs
├── CarParts
│ ├── CarAccessories.cs
│ ├── CarBody.cs
│ ├── CarEngine.cs
│ └── CarModel.cs
├── Facade.csproj
└── Program.cs
├── Flyweight
├── Flyweight.csproj
├── NormalImplementation
│ ├── Clients
│ │ └── CoffeeMaker.cs
│ ├── CoffeeFlavour.cs
│ ├── ICoffeeFlavourFactory.cs
│ ├── Minimal
│ │ └── MinimumMemoryFootprint.cs
│ └── ReducedMemoryFootprintFlavorFactory.cs
├── Program.cs
└── SimpleImplementation
│ ├── ClientObject.cs
│ ├── FlyWeight.cs
│ └── FlyWeightPointer.cs
├── Interpreter
├── Context
│ └── TokenReader.cs
├── Expression
│ ├── AddExpression.cs
│ ├── IExpression.cs
│ ├── NumberExpression.cs
│ └── SubtractExpression.cs
├── Interpreter.csproj
└── Program.cs
├── Iterator
├── Aggregate
│ ├── Aggregate.cs
│ └── ConcreteAggregate.cs
├── BuiltIn
│ ├── MyCollection.cs
│ └── MyCollectionEnumerator.cs
├── Iterator.csproj
├── Iterator
│ ├── ConcreteIterator.cs
│ └── Iterator.cs
└── Program.cs
├── LICENSE
├── Mediator
├── Colleague
│ ├── IUser.cs
│ ├── User.cs
│ └── VipUser.cs
├── Mediator.csproj
├── Mediator
│ ├── ChatMediator.cs
│ └── IChatMediator.cs
└── Program.cs
├── Memento
├── Memento.cs
├── Memento.csproj
├── OriginalObject.cs
└── Program.cs
├── NullObject
├── Animal.cs
├── Dog.cs
├── IAnimal.cs
├── NullObject.csproj
└── Program.cs
├── Observer
├── BuiltInObserver
│ ├── Observer
│ │ ├── GermanyWeatherStation.cs
│ │ ├── IranWeatherStation.cs
│ │ └── UnitedStateWeatherStation.cs
│ └── Subject
│ │ ├── WeatherEventArgs.cs
│ │ └── WeatherReport.cs
├── Observer.csproj
├── ObserverObjects
│ ├── ConcreteObserver.cs
│ └── Observer.cs
├── Program.cs
└── SubjectObjects
│ ├── ConcreteSubject.cs
│ └── Subject.cs
├── Prototype
├── AbstractPrototype
│ └── IPerson.cs
├── ConcretePrototype
│ ├── Dick.cs
│ ├── Harry.cs
│ └── Tom.cs
├── Program.cs
├── Prototype.csproj
└── PrototypeUsage
│ └── Factory.cs
├── Proxy
├── ActualObjects
│ ├── Car.cs
│ ├── Driver.cs
│ └── ICar.cs
├── Program.cs
├── Proxy.csproj
└── Proxy
│ └── ProxyCar.cs
├── README.md
├── RepositoryAndUnitOfWork
├── DomainModels
│ ├── ApplicationUser.cs
│ ├── Article.cs
│ ├── ArticleArticleTag.cs
│ ├── ArticleComment.cs
│ ├── ArticleRating.cs
│ ├── ArticleTag.cs
│ ├── Contact.cs
│ ├── Portfolio.cs
│ ├── SiteOrder.cs
│ └── SlideShow.cs
├── ORM
│ └── FreelancerBlogContext.cs
├── Program.cs
├── Repositories
│ ├── ArticleRepository.cs
│ ├── ContactRepository.cs
│ ├── PortfolioRepository.cs
│ ├── SiteOrderRepository.cs
│ ├── SlideShowRepository.cs
│ └── UserRepository.cs
├── RepositoryAndUnitOfWork.csproj
├── RepositoryInterfaces
│ ├── IArticleRepository.cs
│ ├── IContactRepository.cs
│ ├── IPortfolioRepository.cs
│ ├── IRepository.cs
│ ├── ISiteOrderRepository.cs
│ ├── ISlideShowRepository.cs
│ └── IUserRepository.cs
└── UnitOfWorkParts
│ ├── IUnitOfWork.cs
│ └── UnitOfWork.cs
├── Singleton
├── Program.cs
├── Singleton.csproj
├── SingletonLazy.cs
├── SingletonWithLock.cs
└── SingletonWithoutLock.cs
├── Specification
├── BaseSpecification.cs
├── Basket.cs
├── BasketWithItemsSpecification.cs
├── ISpecification.cs
├── Program.cs
├── Repository.cs
└── Specification.csproj
├── State
├── Legacy
│ ├── GumballMachine.cs
│ └── State.cs
├── Program.cs
├── Refactored
│ ├── Abstraction
│ │ └── IState.cs
│ ├── StateMachineContext
│ │ └── GumballMachine.cs
│ └── VariousStates
│ │ ├── HasQuarterState.cs
│ │ ├── NoQuarterState.cs
│ │ ├── SoldOutState.cs
│ │ ├── SoldState.cs
│ │ └── WinnerState.cs
└── State.csproj
├── Strategy
├── Anbstraction
│ └── IDataReader.cs
├── Implementations
│ ├── JsonDataReader.cs
│ ├── SqlDataReader.cs
│ └── XmlDataReader.cs
├── Program.cs
└── Strategy.csproj
├── TemplateMethod
├── AuditExample
│ ├── Abstraction
│ │ ├── IMessageAuditor.cs
│ │ └── MessageProcessor.cs
│ ├── CancelOrderMessageProcessor.cs
│ └── MoreInfo.txt
├── DrinkExample
│ ├── Abstraction
│ │ └── Beverage.cs
│ └── Implementations
│ │ ├── Coffee.cs
│ │ └── Tea.cs
├── Program.cs
└── TemplateMethod.csproj
└── Visitor
├── Elements
├── BoldText.cs
├── Hyperlink.cs
└── PlainText.cs
├── ObjectStructure
├── Document.cs
└── DocumentPart.cs
├── OldImplementation
└── OldImplementation.cs
├── Program.cs
├── Visitor.csproj
└── Visitors
├── HtmlVisitor.cs
├── IVisitor.cs
└── LatexVisitor.cs
/--wait:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HamidMosalla/CSharpDesignPatterns/6de14a00bc429bcbe2c6bd35199375f7d9863c5a/--wait
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # MSTest test Results
33 | [Tt]est[Rr]esult*/
34 | [Bb]uild[Ll]og.*
35 |
36 | # NUNIT
37 | *.VisualState.xml
38 | TestResult.xml
39 |
40 | # Build Results of an ATL Project
41 | [Dd]ebugPS/
42 | [Rr]eleasePS/
43 | dlldata.c
44 |
45 | # .NET Core
46 | project.lock.json
47 | project.fragment.lock.json
48 | artifacts/
49 | **/Properties/launchSettings.json
50 |
51 | *_i.c
52 | *_p.c
53 | *_i.h
54 | *.ilk
55 | *.meta
56 | *.obj
57 | *.pch
58 | *.pdb
59 | *.pgc
60 | *.pgd
61 | *.rsp
62 | *.sbr
63 | *.tlb
64 | *.tli
65 | *.tlh
66 | *.tmp
67 | *.tmp_proj
68 | *.log
69 | *.vspscc
70 | *.vssscc
71 | .builds
72 | *.pidb
73 | *.svclog
74 | *.scc
75 |
76 | # Chutzpah Test files
77 | _Chutzpah*
78 |
79 | # Visual C++ cache files
80 | ipch/
81 | *.aps
82 | *.ncb
83 | *.opendb
84 | *.opensdf
85 | *.sdf
86 | *.cachefile
87 | *.VC.db
88 | *.VC.VC.opendb
89 |
90 | # Visual Studio profiler
91 | *.psess
92 | *.vsp
93 | *.vspx
94 | *.sap
95 |
96 | # TFS 2012 Local Workspace
97 | $tf/
98 |
99 | # Guidance Automation Toolkit
100 | *.gpState
101 |
102 | # ReSharper is a .NET coding add-in
103 | _ReSharper*/
104 | *.[Rr]e[Ss]harper
105 | *.DotSettings.user
106 |
107 | # JustCode is a .NET coding add-in
108 | .JustCode
109 |
110 | # TeamCity is a build add-in
111 | _TeamCity*
112 |
113 | # DotCover is a Code Coverage Tool
114 | *.dotCover
115 |
116 | # Visual Studio code coverage results
117 | *.coverage
118 | *.coveragexml
119 |
120 | # NCrunch
121 | _NCrunch_*
122 | .*crunch*.local.xml
123 | nCrunchTemp_*
124 |
125 | # MightyMoose
126 | *.mm.*
127 | AutoTest.Net/
128 |
129 | # Web workbench (sass)
130 | .sass-cache/
131 |
132 | # Installshield output folder
133 | [Ee]xpress/
134 |
135 | # DocProject is a documentation generator add-in
136 | DocProject/buildhelp/
137 | DocProject/Help/*.HxT
138 | DocProject/Help/*.HxC
139 | DocProject/Help/*.hhc
140 | DocProject/Help/*.hhk
141 | DocProject/Help/*.hhp
142 | DocProject/Help/Html2
143 | DocProject/Help/html
144 |
145 | # Click-Once directory
146 | publish/
147 |
148 | # Publish Web Output
149 | *.[Pp]ublish.xml
150 | *.azurePubxml
151 | # TODO: Comment the next line if you want to checkin your web deploy settings
152 | # but database connection strings (with potential passwords) will be unencrypted
153 | *.pubxml
154 | *.publishproj
155 |
156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
157 | # checkin your Azure Web App publish settings, but sensitive information contained
158 | # in these scripts will be unencrypted
159 | PublishScripts/
160 |
161 | # NuGet Packages
162 | *.nupkg
163 | # The packages folder can be ignored because of Package Restore
164 | **/packages/*
165 | # except build/, which is used as an MSBuild target.
166 | !**/packages/build/
167 | # Uncomment if necessary however generally it will be regenerated when needed
168 | #!**/packages/repositories.config
169 | # NuGet v3's project.json files produces more ignorable files
170 | *.nuget.props
171 | *.nuget.targets
172 |
173 | # Microsoft Azure Build Output
174 | csx/
175 | *.build.csdef
176 |
177 | # Microsoft Azure Emulator
178 | ecf/
179 | rcf/
180 |
181 | # Windows Store app package directories and files
182 | AppPackages/
183 | BundleArtifacts/
184 | Package.StoreAssociation.xml
185 | _pkginfo.txt
186 | *.appx
187 |
188 | # Visual Studio cache files
189 | # files ending in .cache can be ignored
190 | *.[Cc]ache
191 | # but keep track of directories ending in .cache
192 | !*.[Cc]ache/
193 |
194 | # Others
195 | ClientBin/
196 | ~$*
197 | *~
198 | *.dbmdl
199 | *.dbproj.schemaview
200 | *.jfm
201 | *.pfx
202 | *.publishsettings
203 | orleans.codegen.cs
204 |
205 | # Since there are multiple workflows, uncomment next line to ignore bower_components
206 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
207 | #bower_components/
208 |
209 | # RIA/Silverlight projects
210 | Generated_Code/
211 |
212 | # Backup & report files from converting an old project file
213 | # to a newer Visual Studio version. Backup files are not needed,
214 | # because we have git ;-)
215 | _UpgradeReport_Files/
216 | Backup*/
217 | UpgradeLog*.XML
218 | UpgradeLog*.htm
219 |
220 | # SQL Server files
221 | *.mdf
222 | *.ldf
223 | *.ndf
224 |
225 | # Business Intelligence projects
226 | *.rdl.data
227 | *.bim.layout
228 | *.bim_*.settings
229 |
230 | # Microsoft Fakes
231 | FakesAssemblies/
232 |
233 | # GhostDoc plugin setting file
234 | *.GhostDoc.xml
235 |
236 | # Node.js Tools for Visual Studio
237 | .ntvs_analysis.dat
238 | node_modules/
239 |
240 | # Typescript v1 declaration files
241 | typings/
242 |
243 | # Visual Studio 6 build log
244 | *.plg
245 |
246 | # Visual Studio 6 workspace options file
247 | *.opt
248 |
249 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
250 | *.vbw
251 |
252 | # Visual Studio LightSwitch build output
253 | **/*.HTMLClient/GeneratedArtifacts
254 | **/*.DesktopClient/GeneratedArtifacts
255 | **/*.DesktopClient/ModelManifest.xml
256 | **/*.Server/GeneratedArtifacts
257 | **/*.Server/ModelManifest.xml
258 | _Pvt_Extensions
259 |
260 | # Paket dependency manager
261 | .paket/paket.exe
262 | paket-files/
263 |
264 | # FAKE - F# Make
265 | .fake/
266 |
267 | # JetBrains Rider
268 | .idea/
269 | *.sln.iml
270 |
271 | # CodeRush
272 | .cr/
273 |
274 | # Python Tools for Visual Studio (PTVS)
275 | __pycache__/
276 | *.pyc
277 |
278 | # Cake - Uncomment if you are using it
279 | # tools/**
280 | # !tools/packages.config
281 |
282 | # Telerik's JustMock configuration file
283 | *.jmconfig
284 |
285 | # BizTalk build output
286 | *.btp.cs
287 | *.btm.cs
288 | *.odx.cs
289 | *.xsd.cs
--------------------------------------------------------------------------------
/AbstractFactory/AbstractFactory.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/AbstractFactory/Cars/AbstractCars/FamilyCar.cs:
--------------------------------------------------------------------------------
1 | namespace AbstractFactory.Cars.AbstractCars
2 | {
3 | public abstract class FamilyCar
4 | {
5 | public abstract void Speed(SportsCar abstractFamilyCar);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/AbstractFactory/Cars/AbstractCars/SportsCar.cs:
--------------------------------------------------------------------------------
1 | namespace AbstractFactory.Cars.AbstractCars
2 | {
3 | public abstract class SportsCar
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/AbstractFactory/Cars/ConcreteCars/AudiFamilyCar.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using AbstractFactory.Cars.AbstractCars;
3 |
4 | namespace AbstractFactory.Cars.ConcreteCars
5 | {
6 | class AudiFamilyCar : FamilyCar
7 | {
8 | public override void Speed(SportsCar abstractSportsCar)
9 | {
10 | Console.WriteLine(GetType().Name + " is slower than " + abstractSportsCar.GetType().Name);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/AbstractFactory/Cars/ConcreteCars/AudiSportsCar.cs:
--------------------------------------------------------------------------------
1 | using AbstractFactory.Cars.AbstractCars;
2 |
3 | namespace AbstractFactory.Cars.ConcreteCars
4 | {
5 | class AudiSportsCar : SportsCar
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/AbstractFactory/Cars/ConcreteCars/MercedesFamilyCar.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using AbstractFactory.Cars.AbstractCars;
3 |
4 | namespace AbstractFactory.Cars.ConcreteCars
5 | {
6 | class MercedesFamilyCar : FamilyCar
7 | {
8 | public override void Speed(SportsCar abstractSportsCar)
9 | {
10 | Console.WriteLine(GetType().Name + " is slower than "
11 | + abstractSportsCar.GetType().Name);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AbstractFactory/Cars/ConcreteCars/MercedesSportsCar.cs:
--------------------------------------------------------------------------------
1 | using AbstractFactory.Cars.AbstractCars;
2 |
3 | namespace AbstractFactory.Cars.ConcreteCars
4 | {
5 | class MercedesSportsCar : SportsCar
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/AbstractFactory/Client/Driver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using AbstractFactory.Cars;
5 | using AbstractFactory.Cars.AbstractCars;
6 | using AbstractFactory.Factory;
7 | using AbstractFactory.Factory.AnstractFactory;
8 |
9 | namespace AbstractFactory.Client
10 | {
11 | public class Driver
12 | {
13 | private SportsCar _sportsCar;
14 | private FamilyCar _familyCar;
15 |
16 | public Driver(CarFactory carFactory)
17 | {
18 | _sportsCar = carFactory.CreateSportsCar();
19 | _familyCar = carFactory.CreateFamilyCar();
20 | }
21 |
22 | public void CompareSpeed()
23 | {
24 | _familyCar.Speed(_sportsCar);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AbstractFactory/Factory/AnstractFactory/CarFactory.cs:
--------------------------------------------------------------------------------
1 | using AbstractFactory.Cars.AbstractCars;
2 |
3 | namespace AbstractFactory.Factory.AnstractFactory
4 | {
5 | public abstract class CarFactory
6 | {
7 | public abstract SportsCar CreateSportsCar();
8 | public abstract FamilyCar CreateFamilyCar();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/AbstractFactory/Factory/ConcreteFactory/AudiFactory.cs:
--------------------------------------------------------------------------------
1 | using AbstractFactory.Cars;
2 | using AbstractFactory.Cars.AbstractCars;
3 | using AbstractFactory.Cars.ConcreteCars;
4 | using AbstractFactory.Factory.AnstractFactory;
5 |
6 | namespace AbstractFactory.Factory.ConcreteFactory
7 | {
8 | public class AudiFactory : CarFactory
9 | {
10 | public override SportsCar CreateSportsCar()
11 | {
12 | return new AudiSportsCar();
13 | }
14 |
15 | public override FamilyCar CreateFamilyCar()
16 | {
17 | return new AudiFamilyCar();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/AbstractFactory/Factory/ConcreteFactory/MercedesFactory.cs:
--------------------------------------------------------------------------------
1 | using AbstractFactory.Cars.AbstractCars;
2 | using AbstractFactory.Cars.ConcreteCars;
3 | using AbstractFactory.Factory.AnstractFactory;
4 |
5 | namespace AbstractFactory.Factory.ConcreteFactory
6 | {
7 | public class MercedesFactory : CarFactory
8 | {
9 | public override SportsCar CreateSportsCar()
10 | {
11 | return new MercedesSportsCar();
12 | }
13 |
14 | public override FamilyCar CreateFamilyCar()
15 | {
16 | return new MercedesFamilyCar();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/AbstractFactory/Factory/GenericFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AbstractFactory.Factory
6 | {
7 | public class GenericFactory where T : new()
8 | {
9 | public T CreateObject()
10 | {
11 | return new T();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AbstractFactory/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using AbstractFactory.Cars;
3 | using AbstractFactory.Cars.ConcreteCars;
4 | using AbstractFactory.Client;
5 | using AbstractFactory.Factory;
6 | using AbstractFactory.Factory.AnstractFactory;
7 | using AbstractFactory.Factory.ConcreteFactory;
8 |
9 | namespace AbstractFactory
10 | {
11 | class Program
12 | {
13 | static void Main(string[] args)
14 | {
15 |
16 | /*
17 | More info: https://en.wikipedia.org/wiki/Abstract_factory_pattern
18 | https://csharpdesignpatterns.codeplex.com/wikipage?title=Abstract%20Factory%20Pattern&referringTitle=Home
19 | The Abstract Factory design pattern solves problems like:
20 |
21 | How can an application be independent of how its objects are created?
22 | How can a class be independent of how the objects it requires are created?
23 | How can families of related or dependent objects be created?
24 |
25 | Creating objects directly within the class that requires the objects is inflexible because it commits
26 | the class to particular objects and makes it impossible to change the instantiation later independently
27 | from (without having to change) the class. It stops the class from being reusable if other objects are required,
28 | and it makes the class hard to test because real objects can't be replaced with mock objects.
29 | */
30 |
31 |
32 | CarFactory audiFactory = new AudiFactory();
33 | Driver driver1 = new Driver(audiFactory);
34 | driver1.CompareSpeed();
35 |
36 | CarFactory mercedesFactory = new MercedesFactory();
37 | Driver driver2 = new Driver(mercedesFactory);
38 | driver2.CompareSpeed();
39 |
40 |
41 | var factory = new GenericFactory();
42 | var mercedesSportsCar = factory.CreateObject();
43 | Console.WriteLine(mercedesSportsCar.GetType().ToString());
44 |
45 | Console.ReadKey();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Adapter/Adapted/DatabaseHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Adapter.Adapted
4 | {
5 | class DatabaseHelper
6 | {
7 | public void QueryForChanges()
8 | {
9 | Console.WriteLine("Database queried.");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Adapter/Adapted/WebSiteScanner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Adapter.Adapted
4 | {
5 | class WebSiteScanner
6 | {
7 | public void Scan()
8 | {
9 | Console.WriteLine("Web sites scanned.");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Adapter/Adapted/XmlFileLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Adapter.Adapted
4 | {
5 | class XmlFileLoader
6 | {
7 | public void LoadXML()
8 | {
9 | Console.WriteLine("Xml files loaded.");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Adapter/Adapter.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Adapter/Adapter/Connector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Adapter.Adapter
6 | {
7 | public abstract class Connector
8 | {
9 | public abstract void GetData();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Adapter/Adapter/DatabaseConnector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Adapter.Adapted;
5 |
6 | namespace Adapter.Adapter
7 | {
8 | public class DatabaseConnector : Connector
9 | {
10 | public override void GetData()
11 | {
12 | var databaseHelper = new DatabaseHelper();
13 | databaseHelper.QueryForChanges();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Adapter/Adapter/HttpStreamConnector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Adapter.Adapted;
5 |
6 | namespace Adapter.Adapter
7 | {
8 | public class HttpStreamConnector : Connector
9 | {
10 | public override void GetData()
11 | {
12 | var websiteScanner = new WebSiteScanner();
13 | websiteScanner.Scan();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Adapter/Adapter/XmlFileConnector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Adapter.Adapted;
5 |
6 | namespace Adapter.Adapter
7 | {
8 | public class XmlFileConnector : Connector
9 | {
10 | public override void GetData()
11 | {
12 | var xmlfileLoader = new XmlFileLoader();
13 | xmlfileLoader.LoadXML();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Adapter/Client/TradingDataImporter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Adapter.Adapter;
5 |
6 | namespace Adapter.Client
7 | {
8 | class TradingDataImporter
9 | {
10 | public void ImportData(Connector connector)
11 | {
12 | connector.GetData();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Adapter/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Adapter.Adapter;
3 | using Adapter.Client;
4 |
5 | namespace Adapter
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 |
12 | /*
13 | * The Adapter design pattern solves problems like:
14 | How can a class be reused that does not have an interface that a client requires?
15 | How can classes that have incompatible interfaces work together?
16 | How can an alternative interface be provided for a class?
17 |
18 | Often an (already existing) class can't be reused only
19 | because its interface doesn't conform to the interface clients require.
20 | More info: https://csharpdesignpatterns.codeplex.com/wikipage?title=Adapter%20Pattern&referringTitle=Home
21 | */
22 |
23 |
24 | var tradingdataImporter = new TradingDataImporter();
25 |
26 | Connector databaseConnector = new DatabaseConnector();
27 | tradingdataImporter.ImportData(databaseConnector);
28 |
29 | Connector xmlfileConnector = new XmlFileConnector();
30 | tradingdataImporter.ImportData(xmlfileConnector);
31 |
32 | Connector httpstreamConnector = new HttpStreamConnector();
33 | tradingdataImporter.ImportData(httpstreamConnector);
34 |
35 | Console.ReadKey();
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/Bridge/Abstraction/Repository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Bridge.ImplementorAbstract;
5 |
6 | namespace Bridge.Abstraction
7 | {
8 | public abstract class Repository
9 | {
10 | public abstract void AddObject(DataObject dataObject);
11 | public abstract void CopyObject(DataObject dataObject);
12 | public abstract void RemoveObject(DataObject dataObject);
13 |
14 | public void SaveChanges()
15 | {
16 | Console.WriteLine("Changes were saved");
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Bridge/AbstractionRefined/ClientRepository.cs:
--------------------------------------------------------------------------------
1 | using Bridge.Abstraction;
2 | using Bridge.ImplementorAbstract;
3 |
4 | namespace Bridge.AbstractionRefined
5 | {
6 | public class ClientRepository : Repository
7 | {
8 | public override void AddObject(DataObject dataObject)
9 | {
10 | // Do repository specific work
11 | dataObject.Register();
12 | }
13 |
14 | public override void CopyObject(DataObject dataObject)
15 | {
16 | // Do repository specific work
17 | dataObject.Copy();
18 | }
19 |
20 | public override void RemoveObject(DataObject dataObject)
21 | {
22 | // Do repository specific work
23 | dataObject.Delete();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Bridge/AbstractionRefined/ProductRepository.cs:
--------------------------------------------------------------------------------
1 | using Bridge.Abstraction;
2 | using Bridge.ImplementorAbstract;
3 |
4 | namespace Bridge.AbstractionRefined
5 | {
6 | public class ProductRepository : Repository
7 | {
8 | public override void AddObject(DataObject dataObject)
9 | {
10 | // Do repository specific work
11 | dataObject.Register();
12 | }
13 |
14 | public override void CopyObject(DataObject dataObject)
15 | {
16 | // Do repository specific work
17 | dataObject.Copy();
18 | }
19 |
20 | public override void RemoveObject(DataObject dataObject)
21 | {
22 | // Do repository specific work
23 | dataObject.Delete();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Bridge/Bridge.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Bridge/ImplementorAbstract/DataObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Bridge.ImplementorAbstract
6 | {
7 | public abstract class DataObject
8 | {
9 | public abstract void Register();
10 | public abstract DataObject Copy();
11 | public abstract void Delete();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Bridge/ImplementorConcrete/ClientDataObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Bridge.ImplementorAbstract;
5 |
6 | namespace Bridge.ImplementorConcrete
7 | {
8 | public class ClientDataObject : DataObject
9 | {
10 | public override void Register()
11 | {
12 | Console.WriteLine("ClientDataObject was registered");
13 | }
14 |
15 | public override DataObject Copy()
16 | {
17 | Console.WriteLine("ClientDataObject was copied");
18 | return new ClientDataObject();
19 | }
20 |
21 | public override void Delete()
22 | {
23 | Console.WriteLine("ClientDataObject was deleted");
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Bridge/ImplementorConcrete/ProductDataObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Bridge.ImplementorAbstract;
5 |
6 | namespace Bridge.ImplementorConcrete
7 | {
8 | public class ProductDataObject : DataObject
9 | {
10 | public override void Register()
11 | {
12 | Console.WriteLine("ProductDataObject was registered");
13 | }
14 |
15 | public override DataObject Copy()
16 | {
17 | Console.WriteLine("ProductDataObject was copied");
18 | return new ProductDataObject();
19 | }
20 |
21 | public override void Delete()
22 | {
23 | Console.WriteLine("ProductDataObject was deleted");
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Bridge/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Bridge.AbstractionRefined;
3 | using Bridge.ImplementorConcrete;
4 |
5 | namespace Bridge
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 |
12 | /*
13 | * https://en.wikipedia.org/wiki/Bridge_pattern
14 | What problems can the Bridge design pattern solve?
15 | An abstraction and its implementation should be defined and extended independently from each other.
16 | A compile-time binding between an abstraction and its implementation should be avoided so that an implementation can be selected at run-time.
17 |
18 | When using subclassing, different subclasses implement an abstract class in different ways.
19 | But an implementation is bound to the abstraction at compile-time and can't be changed at run-time.
20 | */
21 |
22 | var clientRepository = new ClientRepository();
23 | var clientDataObject = new ClientDataObject();
24 |
25 | clientRepository.AddObject(clientDataObject);
26 | clientRepository.SaveChanges();
27 |
28 | clientRepository.CopyObject(clientDataObject);
29 | clientRepository.RemoveObject(clientDataObject);
30 | clientRepository.SaveChanges();
31 |
32 | Console.WriteLine("===============================================================");
33 |
34 | var productRepository = new ProductRepository();
35 | var productDataObject = new ProductDataObject();
36 |
37 | productRepository.AddObject(productDataObject);
38 | clientRepository.SaveChanges();
39 |
40 | productRepository.CopyObject(productDataObject);
41 | productRepository.RemoveObject(productDataObject);
42 | productRepository.SaveChanges();
43 |
44 |
45 |
46 |
47 | Console.ReadKey();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Builder/Builder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Builder/Builder/AbstractBuilder/IPhoneBuilder.cs:
--------------------------------------------------------------------------------
1 | using Builder.Builder.Object;
2 |
3 | namespace Builder.Builder.AbstractBuilder
4 | {
5 | interface IPhoneBuilder
6 | {
7 | void BuildScreen();
8 | void BuildBattery();
9 | void BuildOS();
10 | void BuildStylus();
11 | MobilePhone Construct();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Builder/Builder/ConcreteBuilder/AndroidPhoneBuilder.cs:
--------------------------------------------------------------------------------
1 | using Builder.Builder.AbstractBuilder;
2 | using Builder.Builder.Object;
3 | using Builder.Builder.Parts;
4 |
5 | namespace Builder.Builder.ConcreteBuilder
6 | {
7 | class AndroidPhoneBuilder : IPhoneBuilder
8 | {
9 | MobilePhone phone;
10 |
11 | public AndroidPhoneBuilder()
12 | {
13 | phone = new MobilePhone("Android Phone");
14 | }
15 |
16 | public void BuildScreen()
17 | {
18 | phone.PhoneScreen = ScreenType.GorillaGlass;
19 | }
20 |
21 | public void BuildBattery()
22 | {
23 | phone.PhoneBatteryCapacity = BatteryCapacity.ThousandMa;
24 | }
25 |
26 | public void BuildOS()
27 | {
28 | phone.PhoneOS = Builder.Parts.Os.Android;
29 | }
30 |
31 | public void BuildStylus()
32 | {
33 | phone.PhoneStylus = Stylus.Yes;
34 | }
35 |
36 | //finally construct the final phone
37 | public MobilePhone Construct()
38 | {
39 | return phone;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Builder/Builder/ConcreteBuilder/WindowsPhoneBuilder.cs:
--------------------------------------------------------------------------------
1 | using Builder.Builder.AbstractBuilder;
2 | using Builder.Builder.Object;
3 | using Builder.Builder.Parts;
4 |
5 | namespace Builder.Builder.ConcreteBuilder
6 | {
7 | class WindowsPhoneBuilder : IPhoneBuilder
8 | {
9 | MobilePhone phone;
10 |
11 | public WindowsPhoneBuilder()
12 | {
13 | phone = new MobilePhone("Windows Phone");
14 | }
15 |
16 | public void BuildScreen()
17 | {
18 | phone.PhoneScreen = ScreenType.Touch;
19 | }
20 |
21 | public void BuildBattery()
22 | {
23 | phone.PhoneBatteryCapacity = BatteryCapacity.TwoThousandMa;
24 | }
25 |
26 | public void BuildOS()
27 | {
28 | phone.PhoneOS = Builder.Parts.Os.WindowsPhone;
29 | }
30 |
31 | public void BuildStylus()
32 | {
33 | phone.PhoneStylus = Stylus.No;
34 | }
35 |
36 | public MobilePhone Construct()
37 | {
38 | return phone;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Builder/Builder/Director/Manufacturer.cs:
--------------------------------------------------------------------------------
1 | using Builder.Builder.AbstractBuilder;
2 | using Builder.Builder.Object;
3 |
4 | namespace Builder.Builder.Director
5 | {
6 | class Manufacturer
7 | {
8 | public MobilePhone Construct(IPhoneBuilder phoneBuilder)
9 | {
10 | phoneBuilder.BuildBattery();
11 | phoneBuilder.BuildOS();
12 | phoneBuilder.BuildScreen();
13 | phoneBuilder.BuildStylus();
14 | return phoneBuilder.Construct();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Builder/Builder/Object/MobilePhone.cs:
--------------------------------------------------------------------------------
1 | using Builder.Builder.Parts;
2 |
3 | namespace Builder.Builder.Object
4 | {
5 | class MobilePhone
6 | {
7 | public MobilePhone(string name)
8 | {
9 | PhoneName = name;
10 | }
11 |
12 | public string PhoneName { get; }
13 |
14 | public ScreenType PhoneScreen { get; set; }
15 |
16 | public BatteryCapacity PhoneBatteryCapacity { get; set; }
17 |
18 | public Os PhoneOS { get; set; }
19 |
20 | public Stylus PhoneStylus { get; set; }
21 |
22 | public override string ToString()
23 | {
24 | return string.Format("Name: {0}\nScreen: {1}\nBattery {2}\nOS: {3}\nStylus: {4}", PhoneName, PhoneScreen, PhoneBatteryCapacity, PhoneOS, PhoneStylus);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Builder/Builder/Parts/BatteryCapacity.cs:
--------------------------------------------------------------------------------
1 | namespace Builder.Builder.Parts
2 | {
3 | public enum BatteryCapacity
4 | {
5 | ThousandMa = 1000,
6 | TwoThousandMa = 2000,
7 | ThreeThousandMa = 3000
8 | }
9 | }
--------------------------------------------------------------------------------
/Builder/Builder/Parts/Os.cs:
--------------------------------------------------------------------------------
1 | namespace Builder.Builder.Parts
2 | {
3 | public enum Os
4 | {
5 | Android,
6 | WindowsMobile,
7 | WindowsPhone,
8 | Symbian
9 | };
10 | }
--------------------------------------------------------------------------------
/Builder/Builder/Parts/ScreenType.cs:
--------------------------------------------------------------------------------
1 | namespace Builder.Builder.Parts
2 | {
3 | public enum ScreenType
4 | {
5 | Touch,
6 | GorillaGlass,
7 | NonTouch
8 | };
9 | }
--------------------------------------------------------------------------------
/Builder/Builder/Parts/Stylus.cs:
--------------------------------------------------------------------------------
1 | namespace Builder.Builder.Parts
2 | {
3 | public enum Stylus
4 | {
5 | Yes,
6 | No
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/Builder/FluentBuilder/House.cs:
--------------------------------------------------------------------------------
1 | namespace Builder.FluentBuilder
2 | {
3 | internal class House
4 | {
5 | public long Area { set; get; }
6 | public int NumberOfRooms { get; set; }
7 | public bool HasGarage { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/Builder/FluentBuilder/HouseBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Builder.FluentBuilder
6 | {
7 | class HouseBuilder : IHouseBuilder
8 | {
9 | private House _house;
10 |
11 | public HouseBuilder()
12 | {
13 | _house = new House();
14 | }
15 |
16 | public HouseBuilder Area(int area)
17 | {
18 | _house.Area = area;
19 | return this;
20 | }
21 |
22 | public HouseBuilder NumberOfRooms(int numberOfRooms)
23 | {
24 | _house.NumberOfRooms = numberOfRooms;
25 | return this;
26 | }
27 |
28 | public HouseBuilder HasGarage(bool hasGarage)
29 | {
30 | _house.HasGarage = hasGarage;
31 | return this;
32 | }
33 |
34 | public House Build()
35 | {
36 | House result = _house;
37 | _house = null; //prevent multiple invocations of Build()
38 | return result;
39 | }
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Builder/FluentBuilder/IHouseBuilder.cs:
--------------------------------------------------------------------------------
1 | namespace Builder.FluentBuilder
2 | {
3 | internal interface IHouseBuilder
4 | {
5 | House Build();
6 | }
7 | }
--------------------------------------------------------------------------------
/Builder/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Builder.Builder.AbstractBuilder;
3 | using Builder.Builder.ConcreteBuilder;
4 | using Builder.Builder.Director;
5 | using Builder.FluentBuilder;
6 |
7 | namespace Builder
8 | {
9 | class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 | var house = new HouseBuilder()
14 | .Area(500)
15 | .NumberOfRooms(4)
16 | .HasGarage(true)
17 | .Build();
18 |
19 |
20 | //More info: https://www.codeproject.com/Articles/470476/Understanding-and-Implementing-Builder-Pattern-in
21 | //Slightly modified version of above link
22 |
23 | // Lets create the Director first
24 | var manufacturer = new Manufacturer();
25 |
26 | // Now let us create an android phone
27 | IPhoneBuilder androidPhoneBuilder = new AndroidPhoneBuilder();
28 | var androidPhone = manufacturer.Construct(androidPhoneBuilder);
29 |
30 | // Now let us create a Windows Phone
31 | IPhoneBuilder windowsPhoneBuilder = new WindowsPhoneBuilder();
32 | var windowsPhone = manufacturer.Construct(windowsPhoneBuilder);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/ChainOfResponsibility/Abstrations/Handler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ChainOfResponsibility.Abstrations
6 | {
7 | abstract class Handler
8 | {
9 | protected Handler successor;
10 |
11 | public void SetSuccessor(Handler successor)
12 | {
13 | this.successor = successor;
14 | }
15 |
16 | public abstract void HandleRequest(int request);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ChainOfResponsibility/ChainOfResponsibility.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ChainOfResponsibility/Implementations/ConcreteHandler1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ChainOfResponsibility.Abstrations;
5 |
6 | namespace ChainOfResponsibility.Implementations
7 | {
8 | class ConcreteHandler1 : Handler
9 | {
10 | public override void HandleRequest(int request)
11 | {
12 | if (request >= 0 && request < 10)
13 | {
14 | Console.WriteLine("{0} handled request {1}", this.GetType().Name, request);
15 | }
16 | else if (successor != null)
17 | {
18 | successor.HandleRequest(request);
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ChainOfResponsibility/Implementations/ConcreteHandler2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ChainOfResponsibility.Abstrations;
3 |
4 | namespace ChainOfResponsibility.Implementations
5 | {
6 | internal class ConcreteHandler2 : Handler
7 | {
8 | public override void HandleRequest(int request)
9 | {
10 | if (request >= 10 && request < 20)
11 | {
12 | Console.WriteLine("{0} handled request {1}", GetType().Name, request);
13 | }
14 | else if (successor != null)
15 | {
16 | successor.HandleRequest(request);
17 | }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/ChainOfResponsibility/Implementations/ConcreteHandler3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ChainOfResponsibility.Abstrations;
5 |
6 | namespace ChainOfResponsibility.Implementations
7 | {
8 | class ConcreteHandler3 : Handler
9 | {
10 | public override void HandleRequest(int request)
11 | {
12 | if (request >= 20 && request < 30)
13 | {
14 | Console.WriteLine("{0} handled request {1}", this.GetType().Name, request);
15 | }
16 |
17 | else if (successor != null)
18 | {
19 | successor.HandleRequest(request);
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ChainOfResponsibility/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ChainOfResponsibility.Abstrations;
3 | using ChainOfResponsibility.Implementations;
4 |
5 | namespace ChainOfResponsibility
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 |
12 | /*
13 | * More info: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
14 | * http://www.dofactory.com/net/chain-of-responsibility-design-pattern
15 | What problems can the Chain of Responsibility design pattern solve?
16 | Coupling the sender of a request to its receiver should be avoided.
17 | It should be possible that more than one receiver can handle a request.
18 |
19 | Implementing a request directly within the class that sends the request is inflexible because it couples the class to a particular receiver and makes it impossible
20 | to support multiple receivers.
21 | */
22 |
23 |
24 | // Setup Chain of Responsibility
25 | Handler h1 = new ConcreteHandler1();
26 | Handler h2 = new ConcreteHandler2();
27 | Handler h3 = new ConcreteHandler3();
28 | h1.SetSuccessor(h2);
29 | h2.SetSuccessor(h3);
30 |
31 | // Generate and process request
32 | int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
33 |
34 | foreach (int request in requests)
35 | {
36 | h1.HandleRequest(request);
37 | }
38 |
39 | Console.ReadKey();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Command/Client/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Command.CommandInvoker;
3 | using Command.Commands;
4 | using Command.Receiver;
5 |
6 | namespace Command.Client
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 |
13 | /*
14 | More info: https://en.wikipedia.org/wiki/Command_pattern
15 | What problems can the Command design pattern solve?
16 |
17 | Coupling the invoker of a request to a particular request should be avoided.
18 | That is, hard-wired requests should be avoided.
19 | It should be possible to configure an object (that invokes a request) with a request.
20 |
21 | Implementing (hard-wiring) a request directly into a class is inflexible because
22 | it couples the class to a particular request at compile-time,
23 | which makes it impossible to specify a request at run-time.
24 | */
25 |
26 | string argument = Console.ReadLine();
27 |
28 | ISwitchable lamp = new Light();
29 |
30 | //Pass reference to the lamp instance to each command
31 | ICommand switchClose = new CloseSwitchCommand(lamp);
32 | ICommand switchOpen = new OpenSwitchCommand(lamp);
33 |
34 | //Pass reference to instances of the Command objects to the switch
35 | Switch @switch = new Switch(switchClose, switchOpen);
36 |
37 | if (argument == "ON")
38 | {
39 | // Switch (the Invoker) will invoke Execute() on the command object.
40 | @switch.Close();
41 | }
42 | else if (argument == "OFF")
43 | {
44 | //Switch (the Invoker) will invoke the Execute() on the command object.
45 | @switch.Open();
46 | }
47 | else
48 | {
49 | Console.WriteLine("Argument \"ON\" or \"OFF\" is required.");
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Command/Command.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Command/CommandInvoker/Switch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Command.Commands;
5 |
6 | namespace Command.CommandInvoker
7 | {
8 | public class Switch
9 | {
10 | readonly ICommand _closedCommand;
11 | readonly ICommand _openedCommand;
12 |
13 | public Switch(ICommand closedCommand, ICommand openedCommand)
14 | {
15 | this._closedCommand = closedCommand;
16 | this._openedCommand = openedCommand;
17 | }
18 |
19 | //close the circuit/power on
20 | public void Close()
21 | {
22 | this._closedCommand.Execute();
23 | }
24 |
25 | //open the circuit/power off
26 | public void Open()
27 | {
28 | this._openedCommand.Execute();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Command/Commands/CloseSwitchCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows.Input;
5 | using Command.Receiver;
6 |
7 | namespace Command.Commands
8 | {
9 | public class CloseSwitchCommand : ICommand
10 | {
11 | private ISwitchable _switchable;
12 |
13 | public CloseSwitchCommand(ISwitchable switchable)
14 | {
15 | _switchable = switchable;
16 | }
17 |
18 | public void Execute()
19 | {
20 | _switchable.PowerOn();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Command/Commands/ICommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Command.Commands
6 | {
7 | public interface ICommand
8 | {
9 | void Execute();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Command/Commands/OpenSwitchCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Command.Receiver;
5 |
6 | namespace Command.Commands
7 | {
8 | public class OpenSwitchCommand : ICommand
9 | {
10 | private ISwitchable _switchable;
11 |
12 | public OpenSwitchCommand(ISwitchable switchable)
13 | {
14 | _switchable = switchable;
15 | }
16 |
17 | public void Execute()
18 | {
19 | _switchable.PowerOff();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Command/Receiver/ISwitchable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Command.Receiver
6 | {
7 | public interface ISwitchable
8 | {
9 | void PowerOn();
10 | void PowerOff();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Command/Receiver/Light.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Command.Receiver
6 | {
7 | public class Light : ISwitchable
8 | {
9 | public void PowerOn()
10 | {
11 | Console.WriteLine("The light is on");
12 | }
13 |
14 | public void PowerOff()
15 | {
16 | Console.WriteLine("The light is off");
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Composite/ComponentObject/CompositeGraphic.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Composite.ComponentObject
5 | {
6 | internal class CompositeGraphic : IGraphic
7 | {
8 | private string _name;
9 | private readonly List _graphics = new List();
10 |
11 | public CompositeGraphic(string name)
12 | {
13 | _name = name;
14 | }
15 |
16 | public void Add(IGraphic component)
17 | {
18 | _graphics.Add(component);
19 | }
20 |
21 | public void AddRange(params IGraphic[] graphic)
22 | {
23 | _graphics.AddRange(graphic);
24 | }
25 |
26 | public void Remove(IGraphic component)
27 | {
28 | _graphics.Remove(component);
29 | }
30 |
31 | public void Display(int depth)
32 | {
33 | Console.WriteLine(new string('-', depth) + _name);
34 |
35 | foreach (var component in _graphics)
36 | {
37 | component.Display(depth + 2);
38 | }
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Composite/ComponentObject/IGraphic.cs:
--------------------------------------------------------------------------------
1 | namespace Composite.ComponentObject
2 | {
3 | public interface IGraphic
4 | {
5 | void Display(int depth);
6 | }
7 | }
--------------------------------------------------------------------------------
/Composite/Composite.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Composite/LeafObject/Leaf.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Composite.ComponentObject;
3 |
4 | namespace Composite.LeafObject
5 | {
6 | internal class Leaf : IGraphic
7 | {
8 | private readonly string _name;
9 |
10 | public Leaf(string name)
11 | {
12 | _name = name;
13 | }
14 |
15 | public void Display(int depth)
16 | {
17 | Console.WriteLine(new string('-', depth) + _name);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Composite/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Composite.LeafObject;
3 | using Composite.ComponentObject;
4 |
5 | namespace Composite
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | /*
12 | More info: https://en.wikipedia.org/wiki/Composite_pattern
13 | What problems can the Composite design pattern solve?
14 |
15 | A part-whole hierarchy should be represented so that clients can treat part and whole objects uniformly.
16 | A part-whole hierarchy should be represented as tree structure.
17 |
18 | When defining (1) Part objects and (2) Whole objects that act as containers for Part objects,
19 | clients must treat them separately, which complicates client code.
20 | */
21 |
22 | CompositeGraphic root = new CompositeGraphic("root");
23 | root.Add(new Leaf("Leaf A"));
24 | root.Add(new Leaf("Leaf B"));
25 |
26 | CompositeGraphic comp = new CompositeGraphic("Composite X");
27 | comp.AddRange(new Leaf("Leaf XA"), new Leaf("Leaf XB"));
28 |
29 | root.Add(comp);
30 | root.Add(new Leaf("Leaf C"));
31 |
32 |
33 | Leaf leaf = new Leaf("Leaf D");
34 | root.Add(leaf);
35 | root.Remove(leaf);
36 |
37 | root.Display(1);
38 |
39 | Console.ReadKey();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Decorator/Component/ICoffee.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Decorator.Component
6 | {
7 | public interface ICoffee
8 | {
9 | double GetCost();
10 | string GetIngredients();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Decorator/Component/SimpleCoffee.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Decorator.Component
6 | {
7 | public class SimpleCoffee : ICoffee
8 | {
9 | public double GetCost()
10 | {
11 | return 1;
12 | }
13 |
14 | public string GetIngredients()
15 | {
16 | return "Coffee";
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Decorator/Decorator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Decorator/Decorator/CoffeeDecorator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Decorator.Component;
5 |
6 | namespace Decorator.Decorator
7 | {
8 | public abstract class CoffeeDecorator : ICoffee
9 | {
10 | private readonly ICoffee _decoratedCoffee;
11 |
12 | public CoffeeDecorator(ICoffee c)
13 | {
14 | this._decoratedCoffee = c;
15 | }
16 |
17 | public virtual double GetCost()
18 | {
19 | return _decoratedCoffee.GetCost();
20 | }
21 |
22 | public virtual string GetIngredients()
23 | {
24 | return _decoratedCoffee.GetIngredients();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Decorator/Decorator/CoffeeWithMilk.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Decorator.Component;
5 |
6 | namespace Decorator.Decorator
7 | {
8 | public class CoffeeWithMilk : CoffeeDecorator
9 | {
10 | public CoffeeWithMilk(ICoffee c) : base(c) { }
11 |
12 | public override double GetCost()
13 | {
14 | return base.GetCost() + 0.5;
15 | }
16 |
17 | public override string GetIngredients()
18 | {
19 | return base.GetIngredients() + ", Milk";
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Decorator/Decorator/CoffeeWithSprinkles.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Decorator.Component;
5 |
6 | namespace Decorator.Decorator
7 | {
8 | class CoffeeWithSprinkles : CoffeeDecorator
9 | {
10 | public CoffeeWithSprinkles(ICoffee c) : base(c) { }
11 |
12 | public override double GetCost()
13 | {
14 | return base.GetCost() + 0.2;
15 | }
16 |
17 | public override string GetIngredients()
18 | {
19 | return base.GetIngredients() + ", Sprinkles";
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Decorator/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Decorator.Component;
3 | using Decorator.Decorator;
4 |
5 | namespace Decorator
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | /*
12 | * More info: https://en.wikipedia.org/wiki/Decorator_pattern
13 | What problems can the Decorator design pattern solve?
14 | Responsibilities should be added to (and removed from) an object dynamically at run-time.
15 | A flexible alternative to subclassing for extending functionality should be provided.
16 |
17 | When using subclassing, different subclasses extend a class in different ways.
18 | But an extension is bound to the class at compile-time and can't be changed at run-time.
19 | */
20 |
21 | void PrintInfo(ICoffee coffee) => Console.WriteLine("Cost: " + coffee.GetCost() + "; Ingredients: " + coffee.GetIngredients());
22 |
23 | ICoffee c = new SimpleCoffee();
24 | PrintInfo(c);
25 |
26 | c = new CoffeeWithMilk(c);
27 | PrintInfo(c);
28 |
29 | c = new CoffeeWithSprinkles(c);
30 | PrintInfo(c);
31 |
32 |
33 |
34 | var coffeeWithMilk = new CoffeeWithMilk(new SimpleCoffee());
35 | PrintInfo(coffeeWithMilk);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Facade/CarFacade/CarFacade.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Facade.CarParts;
5 |
6 | namespace Facade.CarFacade
7 | {
8 | public class CarFacade
9 | {
10 | private readonly CarAccessories accessories;
11 | private readonly CarBody body;
12 | private readonly CarEngine engine;
13 | private readonly CarModel model;
14 |
15 | public CarFacade()
16 | {
17 | accessories = new CarAccessories();
18 | body = new CarBody();
19 | engine = new CarEngine();
20 | model = new CarModel();
21 | }
22 |
23 | public void CreateCompleteCar()
24 | {
25 | Console.WriteLine("******** Creating a Car **********");
26 | model.SetModel();
27 | engine.SetEngine();
28 | body.SetBody();
29 | accessories.SetAccessories();
30 |
31 | Console.WriteLine("******** Car creation is completed. **********");
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Facade/CarParts/CarAccessories.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Facade.CarParts
6 | {
7 | class CarAccessories
8 | {
9 | public void SetAccessories()
10 | {
11 | Console.WriteLine(" CarAccessories - SetAccessories");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Facade/CarParts/CarBody.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Facade.CarParts
6 | {
7 | class CarBody
8 | {
9 | public void SetBody()
10 | {
11 | Console.WriteLine(" CarBody - SetBody");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Facade/CarParts/CarEngine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Facade.CarParts
6 | {
7 | class CarEngine
8 | {
9 | public void SetEngine()
10 | {
11 | Console.WriteLine(" CarEngine - SetEngine");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Facade/CarParts/CarModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Facade.CarParts
6 | {
7 | class CarModel
8 | {
9 | public void SetModel()
10 | {
11 | Console.WriteLine(" CarModel - SetModel");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Facade/Facade.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Facade/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Facade
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | /*
10 | * More info: https://en.wikipedia.org/wiki/Facade_pattern
11 | What problems can the Facade design pattern solve?
12 |
13 | To make a complex subsystem easier to use,
14 | a simple interface should be provided for a set of interfaces in the subsystem.
15 | The dependencies on a subsystem should be minimized.
16 |
17 | Clients that access a complex subsystem directly refer to (depend on) many different objects
18 | having different interfaces (tight coupling),
19 | which makes the clients hard to implement, change, test, and reuse.
20 | */
21 |
22 | var facade = new CarFacade.CarFacade();
23 |
24 | facade.CreateCompleteCar();
25 |
26 | Console.ReadKey();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Flyweight/Flyweight.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Flyweight/NormalImplementation/Clients/CoffeeMaker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Flyweight.NormalImplementation.Clients
6 | {
7 | public class CoffeeMaker
8 | {
9 | private ReducedMemoryFootprintFlavorFactory _flavourFactory;
10 |
11 | public CoffeeMaker(ReducedMemoryFootprintFlavorFactory flavourFactory)
12 | {
13 | _flavourFactory = flavourFactory;
14 | }
15 |
16 | public void MakeCoffee(string flavour)
17 | {
18 | Console.WriteLine($"Making coffee with {_flavourFactory.GetFlavour(flavour).Flavour} flavor.");
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Flyweight/NormalImplementation/CoffeeFlavour.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Flyweight.NormalImplementation
6 | {
7 | public class CoffeeFlavour
8 | {
9 | private readonly string _flavour;
10 |
11 | public CoffeeFlavour(string flavour)
12 | {
13 | _flavour = flavour;
14 | }
15 |
16 | public string Flavour
17 | {
18 | get { return _flavour; }
19 | }
20 |
21 | public override bool Equals(object obj)
22 | {
23 | if (ReferenceEquals(null, obj)) return false;
24 | return obj is CoffeeFlavour && Equals((CoffeeFlavour)obj);
25 | }
26 |
27 | public bool Equals(CoffeeFlavour other)
28 | {
29 | return string.Equals(_flavour, other._flavour);
30 | }
31 |
32 | public override int GetHashCode()
33 | {
34 | return (_flavour != null ? _flavour.GetHashCode() : 0);
35 | }
36 |
37 | public static bool operator ==(CoffeeFlavour a, CoffeeFlavour b)
38 | {
39 | return Equals(a, b);
40 | }
41 |
42 | public static bool operator !=(CoffeeFlavour a, CoffeeFlavour b)
43 | {
44 | return !Equals(a, b);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Flyweight/NormalImplementation/ICoffeeFlavourFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Flyweight.NormalImplementation
6 | {
7 | public interface ICoffeeFlavourFactory
8 | {
9 | CoffeeFlavour GetFlavour(string flavour);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Flyweight/NormalImplementation/Minimal/MinimumMemoryFootprint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Flyweight.NormalImplementation.Minimal
7 | {
8 | public class MinimumMemoryFootprint : ICoffeeFlavourFactory
9 | {
10 | private readonly ConcurrentDictionary _cache = new ConcurrentDictionary();
11 |
12 | public CoffeeFlavour GetFlavour(string flavour)
13 | {
14 | return _cache.GetOrAdd(flavour, flv => new CoffeeFlavour(flv));
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Flyweight/NormalImplementation/ReducedMemoryFootprintFlavorFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading;
5 |
6 | namespace Flyweight.NormalImplementation
7 | {
8 | public class ReducedMemoryFootprintFlavorFactory : ICoffeeFlavourFactory
9 | {
10 | private readonly object _cacheLock = new object();
11 | private readonly IDictionary _cache = new Dictionary();
12 |
13 | public CoffeeFlavour GetFlavour(string flavour)
14 | {
15 | if (_cache.ContainsKey(flavour)) return _cache[flavour];
16 | var coffeeFlavour = new CoffeeFlavour(flavour);
17 | ThreadPool.QueueUserWorkItem(AddFlavourToCache, coffeeFlavour);
18 | return coffeeFlavour;
19 | }
20 |
21 | private void AddFlavourToCache(object state)
22 | {
23 | var coffeeFlavour = (CoffeeFlavour)state;
24 | if (!_cache.ContainsKey(coffeeFlavour.Flavour))
25 | {
26 | lock (_cacheLock)
27 | {
28 | if (!_cache.ContainsKey(coffeeFlavour.Flavour)) _cache.Add(coffeeFlavour.Flavour, coffeeFlavour);
29 | }
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Flyweight/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Flyweight.NormalImplementation;
3 | using Flyweight.NormalImplementation.Clients;
4 | using Flyweight.NormalImplementation.Minimal;
5 | using Flyweight.SimpleImplementation;
6 |
7 | namespace Flyweight
8 | {
9 | class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 |
14 | /*
15 | * More info: https://en.wikipedia.org/wiki/Flyweight_pattern
16 | What problems can the Flyweight design pattern solve? [2]
17 | Large numbers of objects should be supported efficiently.
18 | Creating large numbers of objects should be avoided.
19 |
20 | When representing large text documents, for example, creating an object for each character in the document
21 | would result in a huge amount of objects that couldn't be processed efficiently.
22 | */
23 |
24 | var simpleClient = new ClientObject();
25 | //it'll share the same static FlyWeightPointer
26 | Console.WriteLine(simpleClient.Company);
27 |
28 |
29 | var flyWeightPointer = new ReducedMemoryFootprintFlavorFactory();
30 | var minimalflyWeightPointer = new MinimumMemoryFootprint();
31 | var coffeeMaker1 = new CoffeeMaker(flyWeightPointer);
32 | var coffeeMaker2 = new CoffeeMaker(flyWeightPointer);
33 | var coffeeMaker3 = new CoffeeMaker(flyWeightPointer);
34 | var coffeeMaker4 = new CoffeeMaker(flyWeightPointer);
35 | coffeeMaker1.MakeCoffee("Pepper?!");
36 | coffeeMaker2.MakeCoffee("Lemon?");
37 | coffeeMaker3.MakeCoffee("Chocolate");
38 | coffeeMaker4.MakeCoffee("Spider");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Flyweight/SimpleImplementation/ClientObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Flyweight.SimpleImplementation
6 | {
7 | public class ClientObject
8 | {
9 | //Here the FlyweightPointer creates a static member Company, which is used for every object of ClientObject.
10 | public string Name { get; set; }
11 | public string Company
12 | {
13 | get
14 | {
15 | return FlyWeightPointer.Company.CompanyName;
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Flyweight/SimpleImplementation/FlyWeight.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Flyweight.SimpleImplementation
6 | {
7 | public class FlyWeight
8 | {
9 | public string CompanyName { get; set; }
10 | public string CompanyLocation { get; set; }
11 | public string CompanyWebSite { get; set; }
12 | //Bulky Data
13 | public byte[] CompanyLogo { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Flyweight/SimpleImplementation/FlyWeightPointer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Flyweight.SimpleImplementation
6 | {
7 | public static class FlyWeightPointer
8 | {
9 | public static readonly FlyWeight Company = new FlyWeight
10 | {
11 | CompanyName = "Abc",
12 | CompanyLocation = "XYZ",
13 | CompanyWebSite = "www.abc.com"
14 | // Load CompanyLogo here
15 | };
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Interpreter/Context/TokenReader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Interpreter.Expression;
4 |
5 | namespace Interpreter.Context
6 | {
7 | public class TokenReader
8 | {
9 | //"+ - 10 2 3"
10 | public IExpression ReadToken(List tokenList)
11 | {
12 | return ReadNextToken(tokenList);
13 | }
14 |
15 | private IExpression ReadNextToken(List tokenList)
16 | {
17 | if (int.TryParse(tokenList.First(), out var i)) //if the token is integer (terminal)
18 | {
19 | tokenList.RemoveAt(0); //process terminal expression
20 | return new NumberExpression(i);
21 | }
22 |
23 | return ReadNonTerminal(tokenList); //process nonTerminal expression
24 | }
25 |
26 | private IExpression ReadNonTerminal(List tokenList)
27 | {
28 | string token = tokenList.First();
29 | tokenList.RemoveAt(0); //read the symbol
30 |
31 | IExpression left = ReadNextToken(tokenList); //read left expression
32 | IExpression right = ReadNextToken(tokenList); //read right expression
33 |
34 | if (token == "+") return new AddExpression(left, right);
35 |
36 | if (token == "-") return new SubtractExpression(left, right);
37 |
38 | return null;
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Interpreter/Expression/AddExpression.cs:
--------------------------------------------------------------------------------
1 | namespace Interpreter.Expression
2 | {
3 | public class AddExpression : IExpression
4 | {
5 | readonly IExpression _leftExpression;
6 | readonly IExpression _rightExpression;
7 |
8 | public AddExpression(IExpression left, IExpression right)
9 | {
10 | _leftExpression = left;
11 | _rightExpression = right;
12 | }
13 |
14 | int IExpression.Interpret()
15 | {
16 | return _leftExpression.Interpret() + _rightExpression.Interpret();
17 | }
18 |
19 | public override string ToString()
20 | {
21 | return $"Add Expression {nameof(_leftExpression)}: {_leftExpression}, {nameof(_rightExpression)}: {_rightExpression}";
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/Interpreter/Expression/IExpression.cs:
--------------------------------------------------------------------------------
1 | namespace Interpreter.Expression
2 | {
3 | public interface IExpression
4 | {
5 | int Interpret();
6 | }
7 | }
--------------------------------------------------------------------------------
/Interpreter/Expression/NumberExpression.cs:
--------------------------------------------------------------------------------
1 | namespace Interpreter.Expression
2 | {
3 | public class NumberExpression : IExpression
4 | {
5 | readonly int _number;
6 |
7 | public NumberExpression(int i)
8 | {
9 | _number = i;
10 | }
11 |
12 | int IExpression.Interpret()
13 | {
14 | return _number;
15 | }
16 |
17 | public override string ToString()
18 | {
19 | return $"Number Expression {nameof(_number)}: {_number}";
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/Interpreter/Expression/SubtractExpression.cs:
--------------------------------------------------------------------------------
1 | namespace Interpreter.Expression
2 | {
3 | public class SubtractExpression : IExpression
4 | {
5 | readonly IExpression _leftExpression;
6 | readonly IExpression _rightExpression;
7 |
8 | public SubtractExpression(IExpression left, IExpression right)
9 | {
10 | _leftExpression = left;
11 | _rightExpression = right;
12 | }
13 |
14 | int IExpression.Interpret()
15 | {
16 | return _leftExpression.Interpret() - _rightExpression.Interpret();
17 | }
18 |
19 | public override string ToString()
20 | {
21 | return $"Subtract Expression {nameof(_leftExpression)}: {_leftExpression}, {nameof(_rightExpression)}: {_rightExpression}";
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/Interpreter/Interpreter.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Interpreter/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Interpreter.Context;
4 | using Interpreter.Expression;
5 |
6 | namespace Interpreter
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | /*
13 | * more info: https://sourcemaking.com/design_patterns/interpreter
14 | * https://www.codeproject.com/Articles/186183/Interpreter-Design-Pattern
15 | Intent
16 | Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
17 | Map a domain to a language, the language to a grammar, and the grammar to a hierarchical object-oriented design.
18 |
19 | Problem
20 | A class of problems occurs repeatedly in a well-defined and well-understood domain.
21 | If the domain were characterized with a "language",
22 | then problems could be easily solved with an interpretation "engine".
23 | */
24 |
25 | string tokenString = "+ - 10 2 3";
26 | var tokenList = new List(tokenString.Split(' '));
27 | IExpression expression = new TokenReader().ReadToken(tokenList);
28 | Console.WriteLine(expression.Interpret()); // (10 - 2) + 3 = 11
29 |
30 |
31 | tokenString = "- + 10 5 - 8 2";
32 | tokenList = new List(tokenString.Split(' '));
33 | expression = new TokenReader().ReadToken(tokenList);
34 | Console.WriteLine(expression.Interpret()); // (10 + 5) - (8 - 2) = 9
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Iterator/Aggregate/Aggregate.cs:
--------------------------------------------------------------------------------
1 | namespace Iterator.Aggregate
2 | {
3 | abstract class Aggregate
4 | {
5 | public abstract Iterator.Iterator CreateIterator();
6 | }
7 | }
--------------------------------------------------------------------------------
/Iterator/Aggregate/ConcreteAggregate.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using Iterator.Iterator;
3 |
4 | namespace Iterator.Aggregate
5 | {
6 | internal class ConcreteAggregate : Aggregate
7 | {
8 | private readonly ArrayList _items = new ArrayList();
9 |
10 | public int Count => _items.Count;
11 |
12 | public object this[int index]
13 | {
14 | get => _items[index];
15 |
16 | set => _items.Insert(index, value);
17 | }
18 |
19 | public override Iterator.Iterator CreateIterator()
20 | {
21 | return new ConcreteIterator(this);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Iterator/BuiltIn/MyCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Iterator.BuiltIn
7 | {
8 | public class MyCollection : IEnumerable
9 | {
10 | public T[] Items = new T[4];
11 | public int CountIndex;
12 |
13 | public T this[int index]
14 | {
15 | get { return Items[index]; }
16 | set { Items[index] = value; }
17 | }
18 |
19 | public void Add(T item)
20 | {
21 | if(Items.Length == CountIndex) Array.Resize(ref Items, Items.Length * 2);
22 |
23 | Items[CountIndex++] = item;
24 | }
25 |
26 | public IEnumerator GetEnumerator()
27 | {
28 | return new MyCollectionEnumerator(this);
29 |
30 | /*
31 | //or simply:
32 | for (int i = 0; i < _countIndex; i++) yield return _items[i];
33 | */
34 | }
35 |
36 | IEnumerator IEnumerable.GetEnumerator()
37 | {
38 | return GetEnumerator();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Iterator/BuiltIn/MyCollectionEnumerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Iterator.BuiltIn
7 | {
8 | class MyCollectionEnumerator : IEnumerator
9 | {
10 | private int index = -1;
11 | private MyCollection _myCollection;
12 |
13 | public MyCollectionEnumerator(MyCollection myCollection)
14 | {
15 | _myCollection = myCollection;
16 | }
17 |
18 | public bool MoveNext()
19 | {
20 | return ++index < _myCollection.CountIndex;
21 | }
22 |
23 | public T Current
24 | {
25 | get
26 | {
27 | if (index < 0 || _myCollection.CountIndex <= index) return default(T);
28 |
29 | return _myCollection.Items[index];
30 | }
31 | }
32 |
33 | object IEnumerator.Current => Current;
34 |
35 |
36 |
37 |
38 |
39 |
40 | public void Dispose() { }
41 |
42 | public void Reset()
43 | {
44 | throw new NotSupportedException();
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Iterator/Iterator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Iterator/Iterator/ConcreteIterator.cs:
--------------------------------------------------------------------------------
1 | using Iterator.Aggregate;
2 |
3 | namespace Iterator.Iterator
4 | {
5 | internal class ConcreteIterator : Iterator
6 | {
7 | private readonly ConcreteAggregate _aggregate;
8 |
9 | private int _current;
10 |
11 | public ConcreteIterator(ConcreteAggregate aggregate)
12 | {
13 | _aggregate = aggregate;
14 | }
15 |
16 | public override object First()
17 | {
18 | return _aggregate[0];
19 | }
20 |
21 | public override object Next()
22 | {
23 | return IsDone() ? null : _aggregate[++_current];
24 | }
25 |
26 | public override object CurrentItem()
27 | {
28 | return _aggregate[_current];
29 | }
30 |
31 | public override bool IsDone()
32 | {
33 | return _current >= _aggregate.Count - 1;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/Iterator/Iterator/Iterator.cs:
--------------------------------------------------------------------------------
1 | namespace Iterator.Iterator
2 | {
3 | abstract class Iterator
4 | {
5 | public abstract object First();
6 | public abstract object Next();
7 | public abstract bool IsDone();
8 | public abstract object CurrentItem();
9 | }
10 | }
--------------------------------------------------------------------------------
/Iterator/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Iterator.Aggregate;
4 | using Iterator.BuiltIn;
5 |
6 | namespace Iterator
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | /*
13 | * More info: https://en.wikipedia.org/wiki/Iterator_pattern
14 | * http://www.dofactory.com/net/iterator-design-pattern
15 | What problems can the Iterator design pattern solve?
16 | The elements of an aggregate object should be accessed and traversed without exposing its representation (data structures).
17 | New traversal operations should be defined for an aggregate object without changing its interface.
18 |
19 | Defining access and traversal operations in the aggregate interface is inflexible
20 | because it commits the aggregate to particular access and traversal operations
21 | and makes it impossible to add new operations later without having to change the aggregate interface.
22 | */
23 |
24 | var a = new ConcreteAggregate
25 | {
26 | [0] = "Item A",
27 | [1] = "Item B",
28 | [2] = "Item C",
29 | [3] = "Item D"
30 | };
31 |
32 | Iterator.Iterator i = a.CreateIterator();
33 |
34 | Console.WriteLine("Iterating over collection:");
35 |
36 | object item = i.First();
37 |
38 | while (item != null)
39 | {
40 | Console.WriteLine(item);
41 | item = i.Next();
42 | }
43 |
44 | Console.WriteLine("========================== using the built in mechanisms or .Net==============================");
45 |
46 | var myCollection = new MyCollection { 2, 3, 4, 5 };
47 |
48 | myCollection.Add(25);
49 | myCollection.Add(34);
50 | myCollection.Add(32);
51 |
52 | foreach (var collectionItem in myCollection)
53 | {
54 | Console.WriteLine(collectionItem);
55 | }
56 |
57 | Console.WriteLine("===============================================================================================");
58 |
59 | var enumerator = myCollection.GetEnumerator();
60 |
61 | while (enumerator.MoveNext())
62 | {
63 | Console.WriteLine(enumerator.Current);
64 | }
65 |
66 | Console.ReadKey();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Hamid Mosalla
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 |
--------------------------------------------------------------------------------
/Mediator/Colleague/IUser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Mediator.Mediator;
5 |
6 | namespace Mediator.Colleague
7 | {
8 | public interface IUser
9 | {
10 | void Send(string msg);
11 | void Receive(string msg);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Mediator/Colleague/User.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Mediator.Mediator;
5 |
6 | namespace Mediator.Colleague
7 | {
8 | public class User : IUser
9 | {
10 | private readonly IChatMediator _mediator;
11 | private readonly string _name;
12 |
13 | public User(IChatMediator med, string name)
14 | {
15 | this._mediator = med;
16 | this._name = name;
17 | }
18 |
19 | public void Send(string msg)
20 | {
21 | Console.WriteLine(this._name + ": Sending Message=" + msg);
22 | _mediator.SendMessage(msg, this);
23 | }
24 |
25 | public void Receive(string msg)
26 | {
27 | Console.WriteLine(this._name + ": Received Message:" + msg);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Mediator/Colleague/VipUser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Mediator.Mediator;
5 |
6 | namespace Mediator.Colleague
7 | {
8 | public class VipUser : IUser
9 | {
10 | private readonly IChatMediator _mediator;
11 | private readonly string _name;
12 |
13 | public VipUser(IChatMediator med, string name)
14 | {
15 | this._mediator = med;
16 | this._name = name;
17 | }
18 |
19 | public void Send(string msg)
20 | {
21 | Console.WriteLine($"VIPuser {this._name} : Sending Message = {msg}");
22 | _mediator.SendMessage(msg, this);
23 | }
24 |
25 | public void Receive(string msg)
26 | {
27 | Console.WriteLine($"VIPUser {this._name} : Received Message: {msg}");
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Mediator/Mediator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Mediator/Mediator/ChatMediator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Mediator.Colleague;
6 |
7 | namespace Mediator.Mediator
8 | {
9 | public class ChatMediator : IChatMediator
10 | {
11 | private readonly List _users;
12 |
13 | public ChatMediator()
14 | {
15 | this._users = new List();
16 | }
17 |
18 | public void AddUser(IUser user)
19 | {
20 | this._users.Add(user);
21 | }
22 |
23 | public void SendMessage(string msg, IUser incommingUser)
24 | {
25 | foreach (var user in _users.Where(user => user != incommingUser))
26 | {
27 | user.Receive(msg);
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Mediator/Mediator/IChatMediator.cs:
--------------------------------------------------------------------------------
1 | using Mediator.Colleague;
2 |
3 | namespace Mediator.Mediator
4 | {
5 | public interface IChatMediator
6 | {
7 | void SendMessage(string msg, IUser user);
8 | void AddUser(IUser user);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Mediator/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Mediator.Colleague;
3 | using Mediator.Mediator;
4 |
5 | namespace Mediator
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | /*
12 | * More info: https://en.wikipedia.org/wiki/Mediator_pattern
13 | What problems can the Mediator design pattern solve?
14 | Tight coupling between a set of interacting objects should be avoided.
15 | It should be possible to change the interaction between a set of objects independently.
16 |
17 | Defining a set of interacting objects by accessing and updating each other directly is inflexible because it tightly couples the objects to each other and makes
18 | it impossible to change the interaction independently from (without having to change) the objects.
19 |
20 | And it stops the objects from being reusable and makes them hard to test.
21 | Tightly coupled objects are hard to implement, change, test, and reuse because they refer to and know about many different objects.
22 | */
23 |
24 | IChatMediator mediator = new ChatMediator();
25 | IUser user1 = new User(mediator, "Hamid");
26 | IUser user2 = new User(mediator, "Lisa");
27 | IUser user3 = new User(mediator, "Saurabh");
28 | IUser user4 = new User(mediator, "David");
29 | IUser vipUser = new VipUser(mediator, "Hans");
30 | mediator.AddUser(user1);
31 | mediator.AddUser(user2);
32 | mediator.AddUser(user3);
33 | mediator.AddUser(user4);
34 | mediator.AddUser(vipUser);
35 |
36 | user1.Send("Hi All");
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Memento/Memento.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Memento
6 | {
7 | public class Memento
8 | {
9 | public readonly Stack StringStates;
10 |
11 | public Memento()
12 | {
13 | this.StringStates = new Stack();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Memento/Memento.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Memento/OriginalObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Memento
6 | {
7 | public class OriginalObject
8 | {
9 | private readonly Memento _memento;
10 |
11 | public string FileState
12 | {
13 | get { return _memento.StringStates.Peek(); }
14 | set => _memento.StringStates.Push(value);
15 | }
16 |
17 | public OriginalObject(string str)
18 | {
19 | _memento = new Memento();
20 | this._memento.StringStates.Push(str);
21 | }
22 |
23 | public void Revert()
24 | {
25 | _memento.StringStates.Pop();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Memento/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Memento
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | /*
10 | * More info: https://en.wikipedia.org/wiki/Memento_pattern
11 | What problems can the Memento design pattern solve?
12 |
13 | The internal state of an object should be saved externally so that the object can be restored to this state later.
14 | The object's encapsulation must not be violated.
15 |
16 | The problem is that a well designed object is encapsulated so that its representation (data structure)
17 | is hidden inside the object and can't be accessed from outside the object.
18 | */
19 |
20 | var fileManager = new OriginalObject("State1");
21 | fileManager.FileState = "State2";
22 | fileManager.FileState = "State3";
23 | fileManager.FileState = "State4";
24 |
25 | Console.WriteLine($"First value {fileManager.FileState}");
26 | fileManager.Revert();
27 | Console.WriteLine($"After first revert {fileManager.FileState}");
28 | fileManager.Revert();
29 | Console.WriteLine($"After second revert {fileManager.FileState}");
30 |
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/NullObject/Animal.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NullObject
6 | {
7 | abstract class Animal : IAnimal
8 | {
9 | public static readonly IAnimal Null = new NullAnimal();
10 |
11 | private class NullAnimal : Animal
12 | {
13 | public override void MakeSound() { }
14 | }
15 |
16 | public abstract void MakeSound();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/NullObject/Dog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NullObject
6 | {
7 | class Dog : IAnimal
8 | {
9 | public void MakeSound()
10 | {
11 | Console.WriteLine("Woof!");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/NullObject/IAnimal.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NullObject
6 | {
7 | interface IAnimal
8 | {
9 | void MakeSound();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/NullObject/NullObject.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NullObject/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NullObject
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | /*
10 | * More info: https://en.wikipedia.org/wiki/Null_object_pattern
11 | * What problems can the Memento design pattern solve?
12 | In most object-oriented languages, such as Java or C#, references may be null.
13 | These references need to be checked to ensure they are not null before invoking any methods,
14 | because methods typically cannot be invoked on null references.
15 |
16 | The Objective-C language takes another approach to this problem and does nothing when sending a message to nil;
17 | if a return value is expected, nil (for objects), 0 (for numeric values), NO (for BOOL values),
18 | or a struct (for struct types) with all its members initialised
19 | to null/0/NO/zero-initialised struct is returned.[2]
20 | */
21 |
22 | //Remember null object is an anti pattern: https://stackoverflow.com/questions/1178399/how-do-i-create-a-null-object-in-c-sharp
23 | IAnimal dog = new Dog();
24 | dog.MakeSound();
25 |
26 | // replace Animal.Null with null and you'll get an exception
27 | IAnimal unknown = Animal.Null;
28 | unknown.MakeSound();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Observer/BuiltInObserver/Observer/GermanyWeatherStation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Observer.BuiltInObserver.Subject;
3 |
4 | namespace Observer.BuiltInObserver.Observer
5 | {
6 | public class GermanyWeatherStation
7 | {
8 | public void GermanyWeatherChanged(object sender, WeatherEventArgs e)
9 | {
10 | Console.WriteLine($"Germany weather station receiving new transmission, temperature now is {e.Temperature + 4}");
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Observer/BuiltInObserver/Observer/IranWeatherStation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Observer.BuiltInObserver.Subject;
3 |
4 | namespace Observer.BuiltInObserver.Observer
5 | {
6 | public class IranWeatherStation
7 | {
8 | public void IranWeatherChanged(object sender, WeatherEventArgs e)
9 | {
10 | Console.WriteLine($"Iran weather station receiving new transmission, temperature now is {e.Temperature + 10}");
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Observer/BuiltInObserver/Observer/UnitedStateWeatherStation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Observer.BuiltInObserver.Subject;
3 |
4 | namespace Observer.BuiltInObserver.Observer
5 | {
6 | public class UnitedStateWeatherStation
7 | {
8 | public void UnitedStateWeatherChanged(object sender, WeatherEventArgs e)
9 | {
10 | Console.WriteLine($"US weather station receiving new transmission, temperature now is {e.Temperature + 2}");
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Observer/BuiltInObserver/Subject/WeatherEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Observer.BuiltInObserver.Subject
4 | {
5 | public class WeatherEventArgs : EventArgs
6 | {
7 | private double _temperature;
8 |
9 | public WeatherEventArgs(double temperature)
10 | {
11 | _temperature = temperature;
12 | }
13 | public double Temperature
14 | {
15 | get { return _temperature; }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Observer/BuiltInObserver/Subject/WeatherReport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Observer.BuiltInObserver.Subject
4 | {
5 | public class WeatherReport
6 | {
7 | public event EventHandler WeatherChanged;
8 |
9 | public virtual void ReportWeather(WeatherEventArgs e)
10 | {
11 | // Make a temporary copy of the event to avoid possibility of
12 | // a race condition if the last subscriber unsubscribes
13 | // immediately after the null check and before the event is raised.
14 | EventHandler handler = WeatherChanged;
15 |
16 | if (handler != null)
17 | {
18 | Console.WriteLine($"Central weather station reporting, new weather is {e.Temperature} C");
19 | handler(this, e);
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Observer/Observer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Observer/ObserverObjects/ConcreteObserver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Observer.SubjectObjects;
3 |
4 | namespace Observer.ObserverObjects
5 | {
6 | internal class ConcreteObserver : Observer
7 | {
8 | private readonly string _name;
9 |
10 | private string _observerState;
11 |
12 | public ConcreteObserver(ConcreteSubject subject, string name)
13 | {
14 | Subject = subject;
15 |
16 | _name = name;
17 | }
18 |
19 | public ConcreteSubject Subject { get; set; }
20 |
21 | public override void Update()
22 | {
23 | _observerState = Subject.SubjectState;
24 |
25 | Console.WriteLine("Observer {0}'s new state is {1}", _name, _observerState);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Observer/ObserverObjects/Observer.cs:
--------------------------------------------------------------------------------
1 | namespace Observer.ObserverObjects
2 | {
3 | abstract class Observer
4 | {
5 | public abstract void Update();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Observer/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Observer.BuiltInObserver;
3 | using Observer.BuiltInObserver.Observer;
4 | using Observer.BuiltInObserver.Subject;
5 | using Observer.ObserverObjects;
6 | using Observer.SubjectObjects;
7 |
8 | namespace Observer
9 | {
10 | class Program
11 | {
12 | static void Main(string[] args)
13 | {
14 | /*
15 | * More info: https://en.wikipedia.org/wiki/Observer_pattern
16 | What problems can the Observer design pattern solve?
17 |
18 | A one-to-many dependency between objects should be defined without making the objects tightly coupled.
19 | It should be ensured that when one object changes state an open-ended number of dependent objects are updated automatically.
20 | It should be possible that one object can notify an open-ended number of other objects.
21 |
22 | Defining a one-to-many dependency between objects by defining one object (subject)
23 | that updates the state of dependent objects directly is inflexible because it commits (tightly couples) the subject to particular dependent objects.
24 |
25 | Tightly coupled objects are hard to implement, change, test,
26 | and reuse because they refer to and know about (how to update) many different objects with different interfaces.
27 | */
28 |
29 |
30 | #region Observer pattern
31 |
32 | // Configure Observer pattern
33 |
34 | ConcreteSubject subject = new ConcreteSubject();
35 |
36 | subject.Attach(new ConcreteObserver(subject, "X"));
37 |
38 | subject.Attach(new ConcreteObserver(subject, "Y"));
39 |
40 | subject.Attach(new ConcreteObserver(subject, "Z"));
41 |
42 |
43 | // Change subject and notify observers
44 |
45 | subject.SubjectState = "ABC";
46 |
47 | subject.Notify();
48 |
49 | #endregion
50 |
51 | #region .Net implementation of observer pattern
52 |
53 | var publisherWeatherStation = new WeatherReport();
54 |
55 | var subscriberGermanyWeatherStation = new GermanyWeatherStation();
56 | var subscriberIranWeatherStation = new IranWeatherStation();
57 | var subscriberUnitedStateWeatherStation = new UnitedStateWeatherStation();
58 |
59 | publisherWeatherStation.WeatherChanged += subscriberGermanyWeatherStation.GermanyWeatherChanged;
60 | publisherWeatherStation.WeatherChanged += subscriberIranWeatherStation.IranWeatherChanged;
61 | publisherWeatherStation.WeatherChanged += subscriberUnitedStateWeatherStation.UnitedStateWeatherChanged;
62 |
63 | publisherWeatherStation.ReportWeather(new WeatherEventArgs(temperature: 30));
64 |
65 | #endregion
66 |
67 | Console.ReadKey();
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Observer/SubjectObjects/ConcreteSubject.cs:
--------------------------------------------------------------------------------
1 | namespace Observer.SubjectObjects
2 | {
3 | class ConcreteSubject : Subject
4 | {
5 | private string _subjectState;
6 |
7 | public string SubjectState
8 | {
9 | get { return _subjectState; }
10 |
11 | set { _subjectState = value; }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Observer/SubjectObjects/Subject.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Observer.SubjectObjects
4 | {
5 | internal abstract class Subject
6 | {
7 | private readonly List _observers = new List();
8 |
9 | public void Attach(ObserverObjects.Observer observer)
10 | {
11 | _observers.Add(observer);
12 | }
13 |
14 | public void Detach(ObserverObjects.Observer observer)
15 | {
16 | _observers.Remove(observer);
17 | }
18 |
19 | public void Notify()
20 | {
21 | foreach (ObserverObjects.Observer o in _observers) o.Update();
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/Prototype/AbstractPrototype/IPerson.cs:
--------------------------------------------------------------------------------
1 | namespace Prototype.AbstractPrototype
2 | {
3 | interface IPerson
4 | {
5 | IPerson Clone();
6 | }
7 | }
--------------------------------------------------------------------------------
/Prototype/ConcretePrototype/Dick.cs:
--------------------------------------------------------------------------------
1 | using Prototype.AbstractPrototype;
2 |
3 | namespace Prototype.ConcretePrototype
4 | {
5 | class Dick : IPerson
6 | {
7 | private string _name = "Dick";
8 |
9 | public IPerson Clone()
10 | {
11 | //shallow copy
12 | return (IPerson)this.MemberwiseClone();
13 |
14 | //deep copy
15 | //return (IPerson)this.Clone();
16 | }
17 |
18 | public override string ToString()
19 | {
20 | return _name;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/Prototype/ConcretePrototype/Harry.cs:
--------------------------------------------------------------------------------
1 | using Prototype.AbstractPrototype;
2 |
3 | namespace Prototype.ConcretePrototype
4 | {
5 | class Harry : IPerson
6 | {
7 | private string _name = "Harry";
8 |
9 | public IPerson Clone()
10 | {
11 | return (IPerson)this.MemberwiseClone();
12 | }
13 |
14 | public override string ToString()
15 | {
16 | return _name;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Prototype/ConcretePrototype/Tom.cs:
--------------------------------------------------------------------------------
1 | using Prototype.AbstractPrototype;
2 |
3 | namespace Prototype.ConcretePrototype
4 | {
5 | class Tom : IPerson
6 | {
7 | private string _name = "Tom";
8 |
9 | public IPerson Clone()
10 | {
11 | return (IPerson)this.MemberwiseClone();
12 | }
13 |
14 | public override string ToString()
15 | {
16 | return _name;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Prototype/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Prototype.AbstractPrototype;
3 | using Prototype.PrototypeUsage;
4 |
5 | namespace Prototype
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 |
12 | /*
13 | * More info: https://sourcemaking.com/design_patterns/prototype
14 | The Prototype design pattern solves problems like:
15 |
16 | Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
17 | Co-opt one instance of a class for use as a breeder of all future instances.
18 | The new operator considered harmful.
19 |
20 | Prototypes are useful when object initialization is expensive, and you anticipate few variations on the initialization parameters.
21 | In this context, Prototype can avoid expensive "creation from scratch", and support cheap cloning of a pre-initialized prototype.
22 |
23 | More info: https://en.wikipedia.org/wiki/Prototype_pattern
24 | This pattern is used to:
25 |
26 | avoid subclasses of an object creator in the client application, like the factory method pattern does.
27 | avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword)
28 | when it is prohibitively expensive for a given application.
29 | */
30 |
31 | var people = new[] { "tom", "dick", "harry" };
32 |
33 | foreach (var item in people)
34 | {
35 | IPerson prototype = Factory.GetPrototype(item);
36 |
37 | Console.WriteLine(item);
38 | }
39 |
40 | Console.WriteLine(Factory.GetPrototype("tom"));
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Prototype/Prototype.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Prototype/PrototypeUsage/Factory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Prototype.AbstractPrototype;
4 | using Prototype.ConcretePrototype;
5 |
6 | namespace Prototype.PrototypeUsage
7 | {
8 | class Factory
9 | {
10 | private static readonly Dictionary Prototypes = new Dictionary();
11 |
12 | static Factory()
13 | {
14 | Prototypes.Add("tom", new Tom());
15 | Prototypes.Add("dick", new Dick());
16 | Prototypes.Add("harry", new Harry());
17 | }
18 |
19 | public static IPerson GetPrototype(string type)
20 | {
21 | try
22 | {
23 | return Prototypes.GetValueOrDefault(type).Clone();
24 | }
25 | catch (NullReferenceException)
26 | {
27 | Console.WriteLine("Prototype with name: " + type + ", doesn't exist");
28 | return null;
29 | }
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Proxy/ActualObjects/Car.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Proxy.ActualObjects
6 | {
7 | public class Car : ICar
8 | {
9 | public void DriveCar()
10 | {
11 | Console.WriteLine("Car has been driven!");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Proxy/ActualObjects/Driver.cs:
--------------------------------------------------------------------------------
1 | namespace Proxy.ActualObjects
2 | {
3 | public class Driver
4 | {
5 | public int Age { get; set; }
6 |
7 | public Driver(int age)
8 | {
9 | this.Age = age;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Proxy/ActualObjects/ICar.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Proxy.ActualObjects
6 | {
7 | interface ICar
8 | {
9 | void DriveCar();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Proxy/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Proxy.ActualObjects;
3 | using Proxy.Proxy;
4 |
5 | namespace Proxy
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 |
12 | /*
13 | * https://en.wikipedia.org/wiki/Proxy_pattern
14 | What problems can the Proxy design pattern solve?
15 | 1-The access to an object should be controlled.
16 | 2-Additional functionality should be provided when accessing an object.
17 | When accessing sensitive objects, for example, it should be possible to check that clients have the needed access rights.
18 | */
19 |
20 | ICar car = new ProxyCar(new Driver(16));
21 | car.DriveCar();
22 |
23 | car = new ProxyCar(new Driver(25));
24 | car.DriveCar();
25 |
26 | Console.ReadKey();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Proxy/Proxy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Proxy/Proxy/ProxyCar.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Proxy.ActualObjects;
5 |
6 | namespace Proxy.Proxy
7 | {
8 | public class ProxyCar : ICar
9 | {
10 | private Driver driver;
11 | private ICar realCar;
12 |
13 | public ProxyCar(Driver driver)
14 | {
15 | this.driver = driver;
16 | this.realCar = new Car();
17 | }
18 |
19 | public void DriveCar()
20 | {
21 | if (driver.Age <= 16)
22 | Console.WriteLine("Sorry, the driver is too young to drive.");
23 | else
24 | this.realCar.DriveCar();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CSharpDesignPatterns
2 | Design pattern samples in C#
3 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/ApplicationUser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Microsoft.AspNetCore.Identity;
4 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
5 |
6 | namespace RepositoryAndUnitOfWork.DomainModels
7 | {
8 | public class ApplicationUser : IdentityUser
9 | {
10 | public string UserFullName { get; set; }
11 | public string UserAddress { get; set; }
12 | public string UserPhoneNumber { get; set; }
13 | public string UserProfileEmail { get; set; }
14 | public string UserAvatar { get; set; }
15 | public string UserBio { get; set; }
16 | public string UserGender { get; set; }
17 | public string UserOccupation { get; set; }
18 | public string UserWebSite { get; set; }
19 | public string UserGoogleProfile { get; set; }
20 | public string UserFacebookProfile { get; set; }
21 | public string UserTwitterProfile { get; set; }
22 | public string UserLinkedInProfile { get; set; }
23 | public int? UserPoints { get; set; }
24 | public string UserSpeciality { get; set; }
25 | public string UserFavourites { get; set; }
26 | public DateTime UserRegisteredDate { get; set; }
27 | public DateTime? UserBanEndDate { get; set; }
28 | public DateTime? UserDateOfBirth { get; set; }
29 | public string UserHowFindUs { get; set; }
30 |
31 |
32 | public virtual ICollection Articles { get; set; }
33 | public virtual ICollection ArticleRatings { get; set; }
34 | public virtual ICollection ArticleComments { get; set; }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/Article.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace RepositoryAndUnitOfWork.DomainModels
5 | {
6 | public class Article
7 | {
8 | public virtual ICollection ArticleArticleTags { get; set; }
9 | public virtual ICollection ArticleRatings { get; set; }
10 | public virtual ICollection ArticleComments { get; set; }
11 |
12 | public int ArticleId { get; set; }
13 | public string ArticleTitle { get; set; }
14 | public string ArticleSummary { get; set; }
15 | public DateTime ArticleDateCreated { get; set; }
16 | public DateTime? ArticleDateModified { get; set; }
17 | public string ArticleBody { get; set; }
18 | public Int64? ArticleViewCount { get; set; }
19 |
20 | public string ArticleStatus { get; set; }
21 |
22 | public bool IsOpenForComment { get; set; }
23 |
24 |
25 | //[ForeignKey("ArticleUserIDfk")]
26 | public virtual ApplicationUser ApplicationUser { get; set; }
27 | public string UserIDfk { get; set; }
28 |
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/ArticleArticleTag.cs:
--------------------------------------------------------------------------------
1 | namespace RepositoryAndUnitOfWork.DomainModels
2 | {
3 | public class ArticleArticleTag
4 | {
5 | public int ArticleId { get; set; }
6 | public int ArticleTagId { get; set; }
7 | public Article Article { get; set; }
8 | public ArticleTag ArticleTag { get; set; }
9 |
10 |
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/ArticleComment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace RepositoryAndUnitOfWork.DomainModels
5 | {
6 | public class ArticleComment
7 | {
8 | public ArticleComment()
9 | {
10 | ArticleCommentChilds = new HashSet();
11 | }
12 |
13 | public int ArticleCommentId { get; set; }
14 | public int? ArticleCommentParentId { get; set; }
15 | public ArticleComment ArticleCommentParent { get; set; }
16 | public virtual ICollection ArticleCommentChilds { get; set; }
17 | public DateTime ArticleCommentDateCreated { get; set; }
18 | public string ArticleCommentName { get; set; }
19 | public string ArticleCommentEmail { get; set; }
20 | public string ArticleCommentWebSite { get; set; }
21 | public string ArticleCommentGravatar { get; set; }
22 | public string ArticleCommentBody { get; set; }
23 | public bool IsCommentApproved { get; set; }
24 |
25 | //[ForeignKey("UserIDfk")]
26 | public virtual ApplicationUser ApplicationUser { get; set; }
27 | public string UserIDfk { get; set; }
28 |
29 | public int ArticleIDfk { get; set; }
30 | //[ForeignKey("ArticleIDfk")]
31 | public virtual Article Article { get; set; }
32 |
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/ArticleRating.cs:
--------------------------------------------------------------------------------
1 | namespace RepositoryAndUnitOfWork.DomainModels
2 | {
3 | public class ArticleRating
4 | {
5 | public int ArticleRatingId { get; set; }
6 | public double ArticleRatingScore { get; set; }
7 |
8 | //[ForeignKey("UserIDfk")]
9 | public virtual ApplicationUser ApplicationUser { get; set; }
10 | public string UserIDfk { get; set; }
11 |
12 | public int ArticleIDfk { get; set; }
13 | //[ForeignKey("ArticleIDfk")]
14 | public virtual Article Article { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/ArticleTag.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace RepositoryAndUnitOfWork.DomainModels
4 | {
5 | public class ArticleTag
6 | {
7 | public virtual ICollection ArticleArticleTags { get; set; }
8 |
9 | public int ArticleTagId { get; set; }
10 | public string ArticleTagName { get; set; }
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/Contact.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RepositoryAndUnitOfWork.DomainModels
4 | {
5 | public class Contact
6 | {
7 | public int ContactId { get; set; }
8 | public DateTime ContactDate { get; set; }
9 | public string ContactName { get; set; }
10 | public string ContactEmail { get; set; }
11 | public string ContactBody { get; set; }
12 | public string ContactPhone { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/Portfolio.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RepositoryAndUnitOfWork.DomainModels
4 | {
5 | public class Portfolio
6 | {
7 | public int PortfolioId { get; set; }
8 | public string PortfolioTitle { get; set; }
9 | public DateTime PortfolioDateCreated { get; set; }
10 | public DateTime PortfolioDateBuilt { get; set; }
11 | public string PortfolioThumbnail { get; set; }
12 | public string PortfolioBody { get; set; }
13 | public string PortfolioSiteAddress { get; set; }
14 | public string PortfolioCategory { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/SiteOrder.cs:
--------------------------------------------------------------------------------
1 | namespace RepositoryAndUnitOfWork.DomainModels
2 | {
3 | public class SiteOrder
4 | {
5 |
6 | public int SiteOrderId { get; set; }
7 |
8 |
9 | //preliminary info - step1
10 | public string SiteOrderWebSiteType { get; set; }
11 | public string SiteOrderNumberOfMockUp { get; set; }
12 | public string SiteOrderDevelopmentComplexity { get; set; }
13 | public int? SiteOrderStaticPageNumber { get; set; }
14 | public bool SiteOrderDoesHaveDatabase { get; set; }
15 | public bool SiteOrderDoesHaveShoppingCart { get; set; }
16 | public bool SiteOrderDoesHaveShoppingCartWithoutRegister { get; set; }
17 | public bool SiteOrderDoesHaveBlog { get; set; }
18 | public bool SiteOrderDoesContentOnUs { get; set; }
19 | public string SiteOrderSupportType { get; set; }
20 |
21 |
22 | //site design info - step2
23 | public bool SiteOrderDoesUseTemplates { get; set; }
24 | public bool SiteOrderDoesUseCustomDesign { get; set; }
25 | public bool SiteOrderIsResponsive { get; set; }
26 | public bool SiteOrderIsOptimizedForMobile { get; set; }
27 | public bool SiteOrderIsOptimizedForAccessibility { get; set; }
28 | public bool SiteOrderIsOptimizedForLightness { get; set; }
29 | public bool SiteOrderDoesWithOkWithJavascriptDisabled { get; set; }
30 | public bool SiteOrderDoesHaveSeo { get; set; }
31 | public string SiteOrderSeoType { get; set; }
32 | public bool SiteOrderDoesHaveSiteMap { get; set; }
33 |
34 |
35 | //structural info - step3
36 | public bool SiteOrderIsCrossPlatform { get; set; }
37 | public bool SiteOrderDoesIncludeUnitTest { get; set; }
38 | public bool SiteOrderIsAsync { get; set; }
39 | public bool SiteOrderDoesConformToSolidDesign { get; set; }
40 | public bool SiteOrderIsSinglePage { get; set; }
41 | public bool SiteOrderDoesUseAjax { get; set; }
42 | public string SiteOrderDoesUseAjaxType { get; set; }
43 | public bool SiteOrderDoesHaveSsl { get; set; }
44 | public bool SiteOrderDoesSourceCodeIncluded { get; set; }
45 | public bool SiteOrderDoesHaveDocumentation { get; set; }
46 |
47 |
48 | //site part info - step4
49 | public bool SiteOrderDoesHaveRegistration { get; set; }
50 | public bool SiteOrderDoesHaveExternalAuth { get; set; }
51 | public bool SiteOrderDoesIncludeUserArea { get; set; }
52 | public bool SiteOrderDoesHaveUserProfile { get; set; }
53 | public bool SiteOrderDoesHaveAdminSection { get; set; }
54 | public bool SiteOrderDoesAdminManageUsers { get; set; }
55 | public bool SiteOrderDoesHaveFileManager { get; set; }
56 | public bool SiteOrderDoesHaveImageGallery { get; set; }
57 | public bool SiteOrderDoesHaveAdvancedHtmlEditor { get; set; }
58 | public bool SiteOrderDoesHaveSlideShow { get; set; }
59 |
60 |
61 | //auxiliary feature info - step5
62 | public bool SiteOrderDoesSupportTagging { get; set; }
63 | public bool SiteOrderDoesSupportCategory { get; set; }
64 | public bool SiteOrderDoesHaveCommenting { get; set; }
65 | public bool SiteOrderDoesHaveRatinging { get; set; }
66 | public bool SiteOrderDoesHaveNewsLetter { get; set; }
67 | public bool SiteOrderDoesHaveFeed { get; set; }
68 | public bool SiteOrderDoesVideoPlaying { get; set; }
69 | public bool SiteOrderDoesHaveForum { get; set; }
70 | public bool SiteOrderDoesHaveSearch { get; set; }
71 | public string SiteOrderSearchType { get; set; }
72 |
73 |
74 | //misc feature info - step6
75 | public bool SiteOrderDoesUseGoogleMap { get; set; }
76 | public bool SiteOrderDoesUseGoogleAnalytics { get; set; }
77 | public bool SiteOrderDoesUseSocialMedia { get; set; }
78 | public bool SiteOrderDoesIncludeChart { get; set; }
79 | public bool SiteOrderDoesIncludeDynamicChart { get; set; }
80 | public bool SiteOrderDoesIncludeAdvancedReport { get; set; }
81 | public bool SiteOrderDoesIncludeDomainAndHosting { get; set; }
82 | public bool SiteOrderDoesSupportIncluded { get; set; }
83 | public bool SiteOrderDoesHaveFaq { get; set; }
84 | public bool SiteOrderDoesHaveComplexFooter { get; set; }
85 |
86 |
87 | //check out info - step7
88 | public string SiteOrderFullName { get; set; }
89 | public string SiteOrderEmail { get; set; }
90 | public string SiteOrderPhone { get; set; }
91 | public string SiteOrderDesc { get; set; }
92 | public string SiteOrderTimeToDeliverMonth { get; set; }
93 | public string SiteOrderExample { get; set; }
94 | public string SiteOrderHowFindUs { get; set; }
95 |
96 |
97 | //final price info
98 | public decimal? SiteOrderFinalPrice { get; set; }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/DomainModels/SlideShow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RepositoryAndUnitOfWork.DomainModels
4 | {
5 | public class SlideShow
6 | {
7 | public int SlideShowId { get; set; }
8 | public DateTime SlideShowDateCreated { get; set; }
9 | public int? SlideShowPriority { get; set; }
10 | public string SlideShowTitle { get; set; }
11 | public string SlideShowBody { get; set; }
12 | public string SlideShowPictrure { get; set; }
13 | public string SlideShowLink { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/ORM/FreelancerBlogContext.cs:
--------------------------------------------------------------------------------
1 |
2 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
3 | using Microsoft.EntityFrameworkCore;
4 | using RepositoryAndUnitOfWork.DomainModels;
5 |
6 | namespace RepositoryAndUnitOfWork.ORM
7 | {
8 | public class FreelancerBlogContext : IdentityDbContext
9 | {
10 | public DbSet Articles { get; set; }
11 | public DbSet ArticleComments { get; set; }
12 | public DbSet ArticleRatings { get; set; }
13 | public DbSet ArticleTags { get; set; }
14 | public DbSet ArticleArticleTags { get; set; }
15 | public DbSet Contacts { get; set; }
16 | public DbSet Portfolios { get; set; }
17 | public DbSet SiteOrders { get; set; }
18 | public DbSet SlideShows { get; set; }
19 |
20 | public FreelancerBlogContext(){ }
21 |
22 | public FreelancerBlogContext(DbContextOptions options) : base(options) { }
23 | }
24 | }
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using RepositoryAndUnitOfWork.ORM;
3 | using RepositoryAndUnitOfWork.UnitOfWorkParts;
4 |
5 | namespace RepositoryAndUnitOfWork
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | /*
12 | What problems can the repository design pattern solve?
13 | In many applications, the business logic accesses data from data stores such as databases,
14 | SharePoint lists, or Web services.
15 | Directly accessing the data can result in the following:
16 |
17 | Duplicated code
18 | A higher potential for programming errors
19 | Weak typing of the business data
20 | Difficulty in centralizing data-related policies such as caching
21 | An inability to easily test the business logic in isolation from external dependencies
22 |
23 | More info: https://msdn.microsoft.com/en-us/library/ff649690.aspx
24 | */
25 |
26 | //usually it's injected into dependent classes within the scope of a request.
27 | var db = new FreelancerBlogContext();
28 |
29 | var unitOfWork = new UnitOfWork(db);
30 |
31 | var allArticleTags = unitOfWork.ArticleRepository.GetAllArticleTags();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/Repositories/ArticleRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using Microsoft.EntityFrameworkCore;
5 | using RepositoryAndUnitOfWork.DomainModels;
6 | using RepositoryAndUnitOfWork.ORM;
7 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
8 |
9 | namespace RepositoryAndUnitOfWork.Repositories
10 | {
11 | public class ArticleRepository : IArticleRepository
12 | {
13 | private FreelancerBlogContext _context;
14 |
15 | public ArticleRepository(FreelancerBlogContext context)
16 | {
17 | _context = context;
18 | }
19 |
20 | #region Article Aggregate Root
21 | public void Add(Article entity)
22 | {
23 | _context.Articles.Add(entity);
24 | }
25 |
26 | public void Remove(Article entity)
27 | {
28 | _context.Articles.Remove(entity);
29 | }
30 |
31 | public void Update(Article entity)
32 | {
33 | _context.Articles.Attach(entity);
34 | _context.Entry(entity).State = EntityState.Modified;
35 | }
36 |
37 | public Task FindByIdAsync(int id)
38 | {
39 | return
40 | _context.Articles.Include(a => a.ApplicationUser)
41 | .Include(a => a.ArticleRatings)
42 | .Include(a => a.ArticleComments)
43 | .SingleOrDefaultAsync(a => a.ArticleId == id);
44 | }
45 |
46 | public Task> GetAllAsync()
47 | {
48 | return
49 | _context.Articles.Include(a => a.ApplicationUser)
50 | .Include(a => a.ArticleRatings)
51 | .Include(a => a.ArticleComments)
52 | .ToListAsync();
53 | }
54 |
55 |
56 |
57 | public Task DeleteArticleAsync(Article article)
58 | {
59 | _context.Articles.Remove(article);
60 | return _context.SaveChangesAsync();
61 | }
62 |
63 | public Task UpdateArticleAsync(Article article)
64 | {
65 | _context.Articles.Attach(article);
66 |
67 | var entity = _context.Entry(article);
68 | entity.State = EntityState.Modified;
69 |
70 | entity.Property(e => e.ArticleDateCreated).IsModified = false;
71 | entity.Property(e => e.ArticleId).IsModified = false;
72 | entity.Property(e => e.ArticleViewCount).IsModified = false;
73 | entity.Property(e => e.UserIDfk).IsModified = false;
74 |
75 | return _context.SaveChangesAsync();
76 | }
77 |
78 | public Task> GetCurrentArticleTagsAsync(int articleId)
79 | {
80 | return
81 | _context.ArticleArticleTags.Where(a => a.ArticleId == articleId)
82 | .Join(_context.ArticleTags.ToList(), aat => aat.ArticleTagId, at => at.ArticleTagId, (aat, at) => at)
83 | .ToListAsync();
84 | }
85 |
86 | public async Task IncreaseArticleViewCount(int articleId)
87 | {
88 | var article = await _context.Articles.SingleAsync(a => a.ArticleId == articleId);
89 |
90 | article.ArticleViewCount += 1;
91 |
92 | return await _context.SaveChangesAsync();
93 | }
94 |
95 | public Task> GetArticlesByTag(int tagId)
96 | {
97 | return
98 | _context.ArticleArticleTags.Where(a => a.ArticleTagId.Equals(tagId))
99 | .Join(
100 | _context.Articles.Include(a => a.ApplicationUser)
101 | .Include(a => a.ArticleComments)
102 | .Include(a => a.ArticleRatings), left => left.ArticleId, right => right.ArticleId,
103 | (aat, a) => a)
104 | .ToListAsync();
105 | }
106 |
107 | public Task> GetLatestArticles(int numberOfArticles)
108 | {
109 | return _context.Articles.OrderByDescending(a => a.ArticleDateCreated).Take(numberOfArticles).ToListAsync();
110 | }
111 | #endregion
112 |
113 | #region ArticleArticleTag
114 | public void AddArticleArticleTag(ArticleArticleTag entity)
115 | {
116 | _context.ArticleArticleTags.Add(entity);
117 | }
118 |
119 | public Task> GetAllArticleArticleTagAsync()
120 | {
121 | return _context.ArticleArticleTags.ToListAsync();
122 | }
123 |
124 | public void AddRangeOfArticleArticleTag(List joinTableArtTagList)
125 | {
126 | _context.ArticleArticleTags.AddRange(joinTableArtTagList);
127 | }
128 | #endregion
129 |
130 | #region ArticleTag
131 | public void AddArticleTag(ArticleTag entity)
132 | {
133 | _context.ArticleTags.Add(entity);
134 | }
135 |
136 | public void RemoveArticleTag(ArticleTag entity)
137 | {
138 | _context.ArticleTags.Remove(entity);
139 | }
140 |
141 | public void UpdateArticleTag(ArticleTag entity)
142 | {
143 | _context.ArticleTags.Attach(entity);
144 | _context.Entry(entity).State = EntityState.Modified;
145 | }
146 |
147 | public Task FindArticleTagByIdAsync(int id)
148 | {
149 | return _context.ArticleTags.SingleOrDefaultAsync(a => a.ArticleTagId.Equals(id));
150 | }
151 |
152 | public IEnumerable GetAllArticleTags()
153 | {
154 | return _context.ArticleTags.ToList();
155 | }
156 |
157 | public Task> GetAllArticleTagsAsync()
158 | {
159 | return _context.ArticleTags.ToListAsync();
160 | }
161 |
162 | public Task GetAllTagNamesArrayAsync()
163 | {
164 | return _context.ArticleTags.Select(a => a.ArticleTagName).ToArrayAsync();
165 | }
166 |
167 | public Task AddRangeOfTags(IEnumerable exceptAddedTags)
168 | {
169 | var listOfAllTags = _context.ArticleTags.ToList();
170 |
171 | foreach (var item in exceptAddedTags)
172 | {
173 | if (listOfAllTags.All(a => a.ArticleTagName != item))
174 | {
175 | _context.ArticleTags.Add(new ArticleTag { ArticleTagName = item });
176 | }
177 | }
178 |
179 | return _context.SaveChangesAsync();
180 | }
181 |
182 | public async Task GetTagsByArticleIdAsync(int articleId)
183 | {
184 | var listOfArticleTags = await _context.ArticleArticleTags.Where(a => a.ArticleId == articleId).ToListAsync();
185 |
186 | var arrayOfTags =
187 | listOfArticleTags.Join(
188 | await _context.ArticleTags.ToListAsync(), a => a.ArticleTagId, t => t.ArticleTagId,
189 | (a, t) => t.ArticleTagName).ToArray();
190 |
191 | return string.Join(",", arrayOfTags);
192 | }
193 |
194 | public Task> FindByTagsName(IEnumerable delimitedTags)
195 | {
196 | return _context.ArticleTags.Join(delimitedTags, a => a.ArticleTagName, e => e, (a, e) => a).ToListAsync();
197 | }
198 |
199 | public Task RemoveRangeOfArticleTags(List tagsToRemove)
200 | {
201 | _context.ArticleTags.RemoveRange(tagsToRemove);
202 | return _context.SaveChangesAsync();
203 | }
204 |
205 | public Task RemoveTagRangeFromArticle(List tagsToRemove, int articleId)
206 | {
207 | var listOfaATags =
208 | _context.ArticleArticleTags.Join(tagsToRemove, a => a.ArticleTagId, t => t.ArticleTagId, (a, t) => a)
209 | .Where(c => c.ArticleId == articleId)
210 | .ToList();
211 |
212 | _context.ArticleArticleTags.RemoveRange(listOfaATags);
213 |
214 | return _context.SaveChangesAsync();
215 | }
216 |
217 | public Task AddTagRangeToArticle(List tagsToAdd, Article article)
218 | {
219 | foreach (var item in tagsToAdd)
220 | {
221 | _context.ArticleArticleTags.Add(new ArticleArticleTag {Article = article, ArticleTag = item});
222 | }
223 |
224 | return _context.SaveChangesAsync();
225 | }
226 |
227 | public Task DeleteArticleTagAsync(ArticleTag model)
228 | {
229 | _context.ArticleTags.Remove(model);
230 |
231 | return _context.SaveChangesAsync();
232 | }
233 |
234 | public Task EditArticleTagAsync(ArticleTag model, string newTagName)
235 | {
236 | model.ArticleTagName = newTagName;
237 | return _context.SaveChangesAsync();
238 | }
239 | #endregion
240 |
241 | #region ArticleRatingRepository
242 | public Task AddRatingForArticle(int id, double rating, string userIDfk)
243 | {
244 | var articleRating = new ArticleRating { ArticleIDfk = id, ArticleRatingScore = rating, UserIDfk = userIDfk };
245 |
246 | _context.ArticleRatings.Add(articleRating);
247 |
248 | return _context.SaveChangesAsync();
249 | }
250 |
251 | public bool IsRatedBefore(int id, string userIDfk)
252 | {
253 | var ratings = _context.ArticleRatings.Where(a => a.ArticleIDfk == id).ToList();
254 |
255 | if (ratings.Count != 0)
256 | {
257 | bool eligibility = ratings.Any(r => r.UserIDfk == userIDfk);
258 |
259 | if (eligibility)
260 | {
261 | return true;
262 | }
263 |
264 | return false;
265 | }
266 |
267 | return false;
268 | }
269 |
270 | public Task UpdateArticleRating(int id, double rating, string userIDfk)
271 | {
272 | var articleRating = _context.ArticleRatings.Single(a => a.ArticleIDfk == id && a.UserIDfk == userIDfk);
273 |
274 | articleRating.ArticleRatingScore = rating;
275 |
276 | return _context.SaveChangesAsync();
277 | }
278 | #endregion
279 |
280 | #region ArticleComment
281 | public Task FindCommentByIdAsync(int id)
282 | {
283 | return _context.ArticleComments.SingleOrDefaultAsync(a => a.ArticleCommentId.Equals(id));
284 | }
285 |
286 | public Task> GetAllCommentAsync()
287 | {
288 | return
289 | _context.ArticleComments.OrderBy(a => a.IsCommentApproved)
290 | .ThenByDescending(a => a.ArticleCommentDateCreated)
291 | .Include(a => a.Article)
292 | .Include(a => a.ApplicationUser)
293 | .ToListAsync();
294 | }
295 |
296 | public Task AddCommentToArticle(ArticleComment articleComment)
297 | {
298 | _context.ArticleComments.Add(articleComment);
299 |
300 | return _context.SaveChangesAsync();
301 | }
302 |
303 | public Task DeleteArticleCommentAsync(ArticleComment model)
304 | {
305 | _context.ArticleComments.Remove(model);
306 | return _context.SaveChangesAsync();
307 | }
308 |
309 | public Task ToggleArticleCommentApproval(ArticleComment model)
310 | {
311 | model.IsCommentApproved = !model.IsCommentApproved;
312 |
313 | return _context.SaveChangesAsync();
314 | }
315 |
316 | public Task EditArticleCommentAsync(ArticleComment model, string newCommentBody)
317 | {
318 | model.ArticleCommentBody = newCommentBody;
319 | return _context.SaveChangesAsync();
320 | }
321 | #endregion
322 | }
323 | }
324 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/Repositories/ContactRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Microsoft.EntityFrameworkCore;
4 | using RepositoryAndUnitOfWork.DomainModels;
5 | using RepositoryAndUnitOfWork.ORM;
6 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
7 |
8 | namespace RepositoryAndUnitOfWork.Repositories
9 | {
10 | public class ContactRepository:IContactRepository
11 | {
12 | private FreelancerBlogContext _context;
13 |
14 | public ContactRepository(FreelancerBlogContext context)
15 | {
16 | _context = context;
17 | }
18 |
19 |
20 | public void Add(Contact entity)
21 | {
22 | _context.Contacts.Add(entity);
23 | }
24 |
25 | public void Remove(Contact entity)
26 | {
27 | _context.Contacts.Remove(entity);
28 | }
29 |
30 | public void Update(Contact entity)
31 | {
32 | _context.Contacts.Attach(entity);
33 | _context.Entry(entity).State = EntityState.Modified;
34 | }
35 |
36 | public Task FindByIdAsync(int id)
37 | {
38 | return _context.Contacts.SingleOrDefaultAsync(c => c.ContactId.Equals(id));
39 | }
40 |
41 | public Task> GetAllAsync()
42 | {
43 | return _context.Contacts.ToListAsync();
44 | }
45 |
46 | public Task AddNewContactAsync(Contact contact)
47 | {
48 | _context.Contacts.Add(contact);
49 | return _context.SaveChangesAsync();
50 | }
51 |
52 | public Task DeleteContactAsync(Contact model)
53 | {
54 | _context.Contacts.Remove(model);
55 | return _context.SaveChangesAsync();
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/Repositories/PortfolioRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using Microsoft.EntityFrameworkCore;
5 | using RepositoryAndUnitOfWork.DomainModels;
6 | using RepositoryAndUnitOfWork.ORM;
7 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
8 |
9 | namespace RepositoryAndUnitOfWork.Repositories
10 | {
11 | public class PortfolioRepository : IPortfolioRepository
12 | {
13 | private FreelancerBlogContext _context;
14 |
15 | public PortfolioRepository(FreelancerBlogContext context)
16 | {
17 | _context = context;
18 | }
19 |
20 |
21 | public void Add(Portfolio entity)
22 | {
23 | _context.Portfolios.Add(entity);
24 | }
25 |
26 | public void Remove(Portfolio entity)
27 | {
28 | _context.Portfolios.Remove(entity);
29 | }
30 |
31 | public void Update(Portfolio entity)
32 | {
33 | _context.Portfolios.Attach(entity);
34 | _context.Entry(entity).State = EntityState.Modified;
35 | }
36 |
37 | public Task FindByIdAsync(int id)
38 | {
39 | return _context.Portfolios.SingleOrDefaultAsync(p=>p.PortfolioId.Equals(id));
40 | }
41 |
42 | public Task> GetAllAsync()
43 | {
44 | return _context.Portfolios.OrderByDescending(p=>p.PortfolioDateCreated).ToListAsync();
45 | }
46 |
47 | public Task AddNewPortfolio(Portfolio portfolio)
48 | {
49 | _context.Portfolios.Add(portfolio);
50 | return _context.SaveChangesAsync();
51 | }
52 |
53 | public Task DeletePortfolioAsync(Portfolio model)
54 | {
55 | _context.Portfolios.Remove(model);
56 | return _context.SaveChangesAsync();
57 | }
58 |
59 | public void Detach(Portfolio model)
60 | {
61 | _context.Entry(model).State = EntityState.Detached;
62 | }
63 |
64 | public Task UpdatePortfolioAsync(Portfolio portfolio)
65 | {
66 | _context.Portfolios.Attach(portfolio);
67 |
68 | var entity = _context.Entry(portfolio);
69 | entity.State = EntityState.Modified;
70 |
71 | entity.Property(e => e.PortfolioDateCreated).IsModified = false;
72 | entity.Property(e => e.PortfolioThumbnail).IsModified = portfolio.PortfolioThumbnail != null;
73 |
74 | return _context.SaveChangesAsync();
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/Repositories/SiteOrderRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Microsoft.EntityFrameworkCore;
4 | using RepositoryAndUnitOfWork.DomainModels;
5 | using RepositoryAndUnitOfWork.ORM;
6 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
7 |
8 | namespace RepositoryAndUnitOfWork.Repositories
9 | {
10 | public class SiteOrderRepository : ISiteOrderRepository
11 | {
12 | private FreelancerBlogContext _context;
13 |
14 | public SiteOrderRepository(FreelancerBlogContext context)
15 | {
16 | _context = context;
17 | }
18 |
19 | public void Add(SiteOrder entity)
20 | {
21 | _context.SiteOrders.Add(entity);
22 | }
23 |
24 | public void Remove(SiteOrder entity)
25 | {
26 | _context.SiteOrders.Remove(entity);
27 | }
28 |
29 | public void Update(SiteOrder entity)
30 | {
31 | _context.SiteOrders.Attach(entity);
32 | _context.Entry(entity).State = EntityState.Modified;
33 | }
34 |
35 | public Task FindByIdAsync(int id)
36 | {
37 | return _context.SiteOrders.SingleAsync(s => s.SiteOrderId.Equals(id));
38 | }
39 |
40 | public Task> GetAllAsync()
41 | {
42 | return _context.SiteOrders.ToListAsync();
43 | }
44 |
45 | public Task AddSiteOrderAsync(SiteOrder siteOrder)
46 | {
47 | _context.SiteOrders.Add(siteOrder);
48 |
49 | return _context.SaveChangesAsync();
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/Repositories/SlideShowRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using Microsoft.EntityFrameworkCore;
5 | using RepositoryAndUnitOfWork.DomainModels;
6 | using RepositoryAndUnitOfWork.ORM;
7 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
8 |
9 | namespace RepositoryAndUnitOfWork.Repositories
10 | {
11 | public class SlideShowRepository : ISlideShowRepository
12 | {
13 | private FreelancerBlogContext _context;
14 |
15 | public SlideShowRepository(FreelancerBlogContext context)
16 | {
17 | _context = context;
18 | }
19 |
20 | public void Add(SlideShow entity)
21 | {
22 | _context.SlideShows.Add(entity);
23 | }
24 |
25 | public void Remove(SlideShow entity)
26 | {
27 | _context.SlideShows.Remove(entity);
28 | }
29 |
30 | public void Update(SlideShow entity)
31 | {
32 | _context.SlideShows.Attach(entity);
33 |
34 | _context.Entry(entity).State = EntityState.Modified;
35 | }
36 |
37 | public Task FindByIdAsync(int id)
38 | {
39 | return _context.SlideShows.SingleOrDefaultAsync(s => s.SlideShowId.Equals(id));
40 | }
41 |
42 | public Task> GetAllAsync()
43 | {
44 | return _context.SlideShows.OrderByDescending(s => s.SlideShowDateCreated).ToListAsync();
45 | }
46 |
47 | public Task AddNewSlideShow(SlideShow slideShow)
48 | {
49 | _context.SlideShows.Add(slideShow);
50 |
51 | return _context.SaveChangesAsync();
52 | }
53 |
54 | public Task DeleteSlideShowAsync(SlideShow model)
55 | {
56 | _context.SlideShows.Remove(model);
57 |
58 | return _context.SaveChangesAsync();
59 | }
60 |
61 | public Task> GetAllAsyncForHomePage()
62 | {
63 | return
64 | _context.SlideShows.OrderBy(s => s.SlideShowPriority)
65 | .ThenByDescending(s => s.SlideShowDateCreated)
66 | .Take(10)
67 | .ToListAsync();
68 | }
69 |
70 | public Task UpdateSlideShowAsync(SlideShow slideshow)
71 | {
72 | _context.SlideShows.Attach(slideshow);
73 |
74 | var entity = _context.Entry(slideshow);
75 | entity.State = EntityState.Modified;
76 |
77 | entity.Property(e => e.SlideShowDateCreated).IsModified = false;
78 | entity.Property(e => e.SlideShowPictrure).IsModified = slideshow.SlideShowPictrure != null;
79 |
80 | return _context.SaveChangesAsync();
81 | }
82 |
83 | public void Detach(SlideShow model)
84 | {
85 | _context.Entry(model).State = EntityState.Detached;
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/Repositories/UserRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Microsoft.EntityFrameworkCore;
4 | using RepositoryAndUnitOfWork.DomainModels;
5 | using RepositoryAndUnitOfWork.ORM;
6 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
7 |
8 | namespace RepositoryAndUnitOfWork.Repositories
9 | {
10 | public class UserRepository : IUserRepository
11 | {
12 | private FreelancerBlogContext _context;
13 |
14 | public UserRepository(FreelancerBlogContext context)
15 | {
16 | _context = context;
17 | }
18 |
19 |
20 | public void Add(ApplicationUser entity)
21 | {
22 | _context.Users.Add(entity);
23 | }
24 |
25 | public void Remove(ApplicationUser entity)
26 | {
27 | _context.Users.Remove(entity);
28 | }
29 |
30 | public void Update(ApplicationUser user)
31 | {
32 | _context.Users.Attach(user);
33 | _context.Entry(user).State = EntityState.Modified;
34 | }
35 |
36 | public Task FindByIdAsync(string id)
37 | {
38 | return _context.Users.SingleAsync(u => u.Id.Equals(id));
39 |
40 | //var userStore = new UserStore(_context);
41 | //var userManager = new UserManager(userStore);
42 | //var user = userManager.FindById(User.Identity.GetUserId());
43 | }
44 |
45 | public Task> GetAllAsync()
46 | {
47 | return _context.Users.ToListAsync();
48 | }
49 |
50 | public async Task UpdateUserProfileAsync(ApplicationUser user)
51 | {
52 | var model = await _context.Users.SingleAsync(u => u.Id.Equals(user.Id));
53 |
54 | model.UserAddress = user.UserAddress;
55 | model.UserProfileEmail = user.UserProfileEmail;
56 | model.UserPhoneNumber = user.UserPhoneNumber;
57 | model.UserAvatar = user.UserAvatar ?? model.UserAvatar;
58 | model.UserBio = user.UserBio;
59 | model.UserDateOfBirth = user.UserDateOfBirth;
60 | model.UserFacebookProfile = user.UserFacebookProfile;
61 | model.UserFavourites = user.UserFavourites;
62 | model.UserFullName = user.UserFullName;
63 | model.UserGender = user.UserGender;
64 | model.UserGoogleProfile = user.UserGoogleProfile;
65 | model.UserHowFindUs = user.UserHowFindUs;
66 | model.UserLinkedInProfile = user.UserLinkedInProfile;
67 | model.UserOccupation = user.UserOccupation;
68 | model.UserSpeciality = user.UserSpeciality;
69 | model.UserTwitterProfile = user.UserTwitterProfile;
70 | model.UserWebSite = user.UserWebSite;
71 |
72 |
73 | return await _context.SaveChangesAsync();
74 | }
75 |
76 | public void Detach(ApplicationUser model)
77 | {
78 | _context.Entry(model).State = EntityState.Detached;
79 | }
80 |
81 | public Task FindByUserNameAsync(string userName)
82 | {
83 | return
84 | _context.Users.Include(u => u.Articles)
85 | .ThenInclude(u => u.ArticleRatings)
86 | .Include(u => u.ArticleComments)
87 | .SingleOrDefaultAsync(u => u.Email.Equals(userName));
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryAndUnitOfWork.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | All
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryInterfaces/IArticleRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using RepositoryAndUnitOfWork.DomainModels;
4 |
5 | namespace RepositoryAndUnitOfWork.RepositoryInterfaces
6 | {
7 | public interface IArticleRepository : IRepository
8 | {
9 | #region Article Aggregate Root
10 | Task UpdateArticleAsync(Article article);
11 |
12 | Task DeleteArticleAsync(Article article);
13 | Task> GetCurrentArticleTagsAsync(int articleId);
14 |
15 | Task IncreaseArticleViewCount(int articleId);
16 |
17 | Task> GetArticlesByTag(int tagId);
18 | Task> GetLatestArticles(int numberOfArticles);
19 | #endregion
20 |
21 | #region ArticleArticleTag
22 | void AddArticleArticleTag(ArticleArticleTag entity);
23 |
24 | Task> GetAllArticleArticleTagAsync();
25 |
26 | void AddRangeOfArticleArticleTag(List joinTableArtTagList);
27 | #endregion
28 |
29 | #region ArticleTag
30 |
31 | void AddArticleTag(ArticleTag entity);
32 |
33 | void RemoveArticleTag(ArticleTag entity);
34 |
35 | void UpdateArticleTag(ArticleTag entity);
36 |
37 | Task FindArticleTagByIdAsync(int id);
38 |
39 | IEnumerable GetAllArticleTags();
40 |
41 | Task> GetAllArticleTagsAsync();
42 | Task GetAllTagNamesArrayAsync();
43 |
44 | Task AddRangeOfTags(IEnumerable exceptAddedTags);
45 |
46 | Task GetTagsByArticleIdAsync(int articleId);
47 |
48 | Task> FindByTagsName(IEnumerable delimitedTags);
49 |
50 | Task RemoveRangeOfArticleTags(List tagsToRemove);
51 |
52 | Task RemoveTagRangeFromArticle(List tagsToRemove, int articleId);
53 |
54 | Task AddTagRangeToArticle(List tagsToAdd, Article article);
55 | Task DeleteArticleTagAsync(ArticleTag model);
56 | Task EditArticleTagAsync(ArticleTag model, string newTagName);
57 | #endregion
58 |
59 | #region ArticleRating
60 | Task AddRatingForArticle(int id, double rating, string userIDfk);
61 |
62 | bool IsRatedBefore(int id, string userIDfk);
63 |
64 | Task UpdateArticleRating(int id, double rating, string userIDfk);
65 | #endregion
66 |
67 | #region ArticleComment
68 | Task FindCommentByIdAsync(int id);
69 | Task> GetAllCommentAsync();
70 | Task AddCommentToArticle(ArticleComment articleComment);
71 | Task DeleteArticleCommentAsync(ArticleComment model);
72 | Task ToggleArticleCommentApproval(ArticleComment model);
73 | Task EditArticleCommentAsync(ArticleComment model, string newCommentBody);
74 | #endregion
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryInterfaces/IContactRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using RepositoryAndUnitOfWork.DomainModels;
3 |
4 | namespace RepositoryAndUnitOfWork.RepositoryInterfaces
5 | {
6 | public interface IContactRepository : IRepository
7 | {
8 | Task AddNewContactAsync(Contact contact);
9 | Task DeleteContactAsync(Contact model);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryInterfaces/IPortfolioRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using RepositoryAndUnitOfWork.DomainModels;
3 |
4 | namespace RepositoryAndUnitOfWork.RepositoryInterfaces
5 | {
6 | public interface IPortfolioRepository : IRepository
7 | {
8 | Task AddNewPortfolio(Portfolio portfolio);
9 | Task DeletePortfolioAsync(Portfolio model);
10 | void Detach(Portfolio model);
11 | Task UpdatePortfolioAsync(Portfolio portfolio);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryInterfaces/IRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 |
4 | namespace RepositoryAndUnitOfWork.RepositoryInterfaces
5 | {
6 | public interface IRepository where T : class
7 | {
8 | void Add(T entity);
9 | void Remove(T entity);
10 | void Update(T entity);
11 | Task FindByIdAsync(TKey id);
12 | Task > GetAllAsync();
13 |
14 | // redundant, redundant, Unit Of Work will handle it
15 | //void Save();
16 |
17 | // too generic, hard to implement for other providers
18 | //IQueryable Find(Expression> predicate);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryInterfaces/ISiteOrderRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using RepositoryAndUnitOfWork.DomainModels;
3 |
4 | namespace RepositoryAndUnitOfWork.RepositoryInterfaces
5 | {
6 | public interface ISiteOrderRepository : IRepository
7 | {
8 | Task AddSiteOrderAsync(SiteOrder siteOrder);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryInterfaces/ISlideShowRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using RepositoryAndUnitOfWork.DomainModels;
4 |
5 | namespace RepositoryAndUnitOfWork.RepositoryInterfaces
6 | {
7 | public interface ISlideShowRepository : IRepository
8 | {
9 | Task AddNewSlideShow(SlideShow slideShow);
10 | Task DeleteSlideShowAsync(SlideShow model);
11 | Task> GetAllAsyncForHomePage();
12 | Task UpdateSlideShowAsync(SlideShow slideshow);
13 | void Detach(SlideShow model);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/RepositoryInterfaces/IUserRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using RepositoryAndUnitOfWork.DomainModels;
3 |
4 | namespace RepositoryAndUnitOfWork.RepositoryInterfaces
5 | {
6 | public interface IUserRepository : IRepository
7 | {
8 | Task UpdateUserProfileAsync(ApplicationUser user);
9 | void Detach(ApplicationUser model);
10 | Task FindByUserNameAsync(string userName);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/UnitOfWorkParts/IUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
4 |
5 | namespace RepositoryAndUnitOfWork.UnitOfWorkParts
6 | {
7 | public interface IUnitOfWork : IDisposable
8 | {
9 | IArticleRepository ArticleRepository { get; }
10 | IUserRepository UserRepository { get; }
11 | IContactRepository ContactRepository { get; }
12 | IPortfolioRepository PortfolioRepository { get; }
13 | ISiteOrderRepository SiteOrderRepository { get; }
14 | ISlideShowRepository SlideShowRepository { get; }
15 | int Save();
16 | Task SaveAsync();
17 | new void Dispose();
18 | }
19 | }
--------------------------------------------------------------------------------
/RepositoryAndUnitOfWork/UnitOfWorkParts/UnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using RepositoryAndUnitOfWork.ORM;
4 | using RepositoryAndUnitOfWork.Repositories;
5 | using RepositoryAndUnitOfWork.RepositoryInterfaces;
6 |
7 | namespace RepositoryAndUnitOfWork.UnitOfWorkParts
8 | {
9 | public class UnitOfWork : IUnitOfWork
10 | {
11 |
12 | private readonly FreelancerBlogContext _context;
13 |
14 | public UnitOfWork(FreelancerBlogContext context)
15 | {
16 | _context = context;
17 | }
18 |
19 | private IArticleRepository _articleRepository;
20 | private IUserRepository _userRepository;
21 | private IContactRepository _contactRepository;
22 | private IPortfolioRepository _portfolioRepository;
23 | private ISiteOrderRepository _siteOrderRepository;
24 | private ISlideShowRepository _slideShowRepository;
25 |
26 | public IArticleRepository ArticleRepository
27 | {
28 | get
29 | {
30 | if (this._articleRepository == null)
31 | {
32 | this._articleRepository = new ArticleRepository(_context);
33 | }
34 | return _articleRepository;
35 | }
36 | }
37 | public IUserRepository UserRepository
38 | {
39 | get
40 | {
41 | if (this._userRepository == null)
42 | {
43 | this._userRepository = new UserRepository(_context);
44 | }
45 | return _userRepository;
46 | }
47 | }
48 | public IContactRepository ContactRepository
49 | {
50 | get
51 | {
52 | if (this._contactRepository == null)
53 | {
54 | this._contactRepository = new ContactRepository(_context);
55 | }
56 | return _contactRepository;
57 | }
58 | }
59 | public IPortfolioRepository PortfolioRepository
60 | {
61 | get
62 | {
63 | if (this._portfolioRepository == null)
64 | {
65 | this._portfolioRepository = new PortfolioRepository(_context);
66 | }
67 | return _portfolioRepository;
68 | }
69 | }
70 | public ISiteOrderRepository SiteOrderRepository
71 | {
72 | get
73 | {
74 | if (this._siteOrderRepository == null)
75 | {
76 | this._siteOrderRepository = new SiteOrderRepository(_context);
77 | }
78 | return _siteOrderRepository;
79 | }
80 | }
81 | public ISlideShowRepository SlideShowRepository
82 | {
83 | get
84 | {
85 | if (this._slideShowRepository == null)
86 | {
87 | this._slideShowRepository = new SlideShowRepository(_context);
88 | }
89 | return _slideShowRepository;
90 | }
91 | }
92 |
93 | public int Save()
94 | {
95 | return _context.SaveChanges();
96 | }
97 |
98 | public Task SaveAsync()
99 | {
100 | return _context.SaveChangesAsync();
101 | }
102 |
103 | private bool _disposed = false;
104 |
105 | protected virtual void Dispose(bool disposing)
106 | {
107 | if (!this._disposed)
108 | {
109 | if (disposing)
110 | {
111 | _context.Dispose();
112 | }
113 | }
114 | this._disposed = true;
115 | }
116 |
117 | public void Dispose()
118 | {
119 | Dispose(true);
120 | GC.SuppressFinalize(this);
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/Singleton/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Singleton
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | /*
10 | More info: http://csharpindepth.com/Articles/General/Singleton.aspx
11 | */
12 |
13 | Console.WriteLine("Hello World!");
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Singleton/Singleton.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Singleton/SingletonLazy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Singleton
6 | {
7 | public sealed class SingletonLazy
8 | {
9 | private static readonly Lazy lazy = new Lazy(() => new SingletonLazy());
10 |
11 | public static SingletonLazy Instance { get { return lazy.Value; } }
12 |
13 | private SingletonLazy()
14 | {
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Singleton/SingletonWithLock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Singleton
6 | {
7 | public sealed class SingletonWithLock
8 | {
9 | private static SingletonWithLock instance = null;
10 | private static readonly object padlock = new object();
11 |
12 | SingletonWithLock()
13 | {
14 | }
15 |
16 | public static SingletonWithLock Instance
17 | {
18 | get
19 | {
20 | lock (padlock)
21 | {
22 | if (instance == null)
23 | {
24 | instance = new SingletonWithLock();
25 | }
26 | return instance;
27 | }
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Singleton/SingletonWithoutLock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Singleton
6 | {
7 | public sealed class SingletonWithoutLock
8 | {
9 | private static readonly SingletonWithoutLock instance = new SingletonWithoutLock();
10 |
11 | // Explicit static constructor to tell C# compiler
12 | // not to mark type as beforefieldinit
13 | static SingletonWithoutLock()
14 | {
15 | }
16 |
17 | private SingletonWithoutLock()
18 | {
19 | }
20 |
21 | public static SingletonWithoutLock Instance
22 | {
23 | get
24 | {
25 | return instance;
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Specification/BaseSpecification.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq.Expressions;
4 | using System.Text;
5 | using Specification;
6 |
7 | namespace Specification
8 | {
9 | // https://github.com/dotnet-architecture/eShopOnWeb
10 | public abstract class BaseSpecification : ISpecification
11 | {
12 | public BaseSpecification(Expression> criteria)
13 | {
14 | Criteria = criteria;
15 | }
16 | public Expression> Criteria { get; }
17 | public List>> Includes { get; } = new List>>();
18 | public List IncludeStrings { get; } = new List();
19 |
20 | protected virtual void AddInclude(Expression> includeExpression)
21 | {
22 | Includes.Add(includeExpression);
23 | }
24 | // string-based includes allow for including children of children, e.g. Basket.Items.Product
25 | protected virtual void AddInclude(string includeString)
26 | {
27 | IncludeStrings.Add(includeString);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Specification/Basket.cs:
--------------------------------------------------------------------------------
1 | namespace Specification
2 | {
3 | public class Basket
4 | {
5 | public object Items { get; set; }
6 | public int Id { get; set; }
7 | public string BuyerId { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/Specification/BasketWithItemsSpecification.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Specification
6 | {
7 | public class BasketWithItemsSpecification : BaseSpecification
8 | {
9 | public BasketWithItemsSpecification(int basketId)
10 | : base(b => b.Id == basketId)
11 | {
12 | AddInclude(b => b.Items);
13 | }
14 | public BasketWithItemsSpecification(string buyerId)
15 | : base(b => b.BuyerId == buyerId)
16 | {
17 | AddInclude(b => b.Items);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Specification/ISpecification.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq.Expressions;
4 | using System.Text;
5 |
6 | namespace Specification
7 | {
8 | // https://github.com/dotnet-architecture/eShopOnWeb
9 | public interface ISpecification
10 | {
11 | Expression> Criteria { get; }
12 | List>> Includes { get; }
13 | List IncludeStrings { get; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Specification/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Specification
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | Console.WriteLine("Hello World!");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Specification/Repository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Specification
6 | {
7 | public class Repository
8 | {
9 | //public IEnumerable List(ISpecification spec)
10 | //{
11 | // // fetch a Queryable that includes all expression-based includes
12 | // var queryableResultWithIncludes = spec.Includes
13 | // .Aggregate(_dbContext.Set().AsQueryable(),
14 | // (current, include) => current.Include(include));
15 |
16 | // // modify the IQueryable to include any string-based include statements
17 | // var secondaryResult = spec.IncludeStrings
18 | // .Aggregate(queryableResultWithIncludes,
19 | // (current, include) => current.Include(include));
20 |
21 | // // return the result of the query using the specification's criteria expression
22 | // return secondaryResult
23 | // .Where(spec.Criteria)
24 | // .AsEnumerable();
25 | //}
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Specification/Specification.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.2
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/State/Legacy/GumballMachine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace State.Legacy
4 | {
5 | public class GumballMachine
6 | {
7 | private int _count;
8 | private State _state = State.NoQuarters;
9 |
10 | public GumballMachine(int count)
11 | {
12 | _count = count;
13 | }
14 |
15 | public void InsertQuarter()
16 | {
17 | switch (_state)
18 | {
19 | case State.NoQuarters:
20 | _state = State.HasQuarters;
21 | Console.WriteLine("Inserted a quarter");
22 | break;
23 | case State.Sold:
24 | Console.WriteLine("Please wait for current gumball to come out");
25 | break;
26 | case State.HasQuarters:
27 | Console.WriteLine("Can't add more quarters");
28 | break;
29 | case State.NoGumballs:
30 | Console.WriteLine("Out of Stock");
31 | break;
32 | default:
33 | throw new ArgumentOutOfRangeException();
34 | }
35 | }
36 |
37 | public void EjectQuarter()
38 | {
39 | switch (_state)
40 | {
41 | case State.NoQuarters:
42 | Console.WriteLine("Nothing to eject");
43 | break;
44 | case State.Sold:
45 | Console.WriteLine("Sorry, you have already turned the crank");
46 | break;
47 | case State.HasQuarters:
48 | Console.WriteLine("Ejecting..");
49 | _state = State.NoQuarters;
50 | break;
51 | case State.NoGumballs:
52 | Console.WriteLine("Can't eject, never accepted quarters");
53 | break;
54 | default:
55 | throw new ArgumentOutOfRangeException();
56 | }
57 | }
58 |
59 | public void TurnCrank()
60 | {
61 | switch (_state)
62 | {
63 | case State.NoQuarters:
64 | Console.WriteLine("Insert quarter First");
65 | break;
66 | case State.Sold:
67 | Console.WriteLine("Turning twice won't get you a gumball");
68 | break;
69 | case State.HasQuarters:
70 | Console.WriteLine("Getting gumball...");
71 | _state = State.Sold;
72 | Dispense();
73 | break;
74 | case State.NoGumballs:
75 | Console.WriteLine("Out of Stock");
76 | break;
77 | default:
78 | throw new ArgumentOutOfRangeException();
79 | }
80 | }
81 |
82 | private void Dispense()
83 | {
84 | switch (_state)
85 | {
86 | case State.NoQuarters:
87 | Console.WriteLine("You need to pay first");
88 | break;
89 | case State.Sold:
90 | Console.WriteLine("A Gumball comes rolling out");
91 | _count--;
92 | _state = _count == 0 ? _state = State.NoGumballs : State.NoQuarters;
93 | break;
94 | case State.HasQuarters:
95 | case State.NoGumballs:
96 | Console.WriteLine("Can't dispense");
97 | break;
98 | default:
99 | throw new ArgumentOutOfRangeException();
100 | }
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/State/Legacy/State.cs:
--------------------------------------------------------------------------------
1 | namespace State.Legacy
2 | {
3 | public enum State
4 | {
5 | Sold, HasQuarters, NoQuarters, NoGumballs
6 | }
7 | }
--------------------------------------------------------------------------------
/State/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using State.Refactored.StateMachineContext;
3 |
4 | namespace State
5 | {
6 | static class Program
7 | {
8 | public static void Main()
9 | {
10 | /*https://stackoverflow.com/a/30424503/1650277
11 | What problems can the State design pattern solve?
12 |
13 | An object should change its behavior when its internal state changes.
14 | State-specific behavior should be defined independently.
15 | That is, new states should be added and the behavior of
16 | existing states should be changed independently.
17 |
18 | Implementing state-specific behavior directly within a class is inflexible because
19 | it commits the class to a particular behavior and makes it impossible to add a new state
20 | or change the behavior of an existing state later independently from (without changing) the class.
21 | *
22 | * Strategy pattern vs State pattern
23 | States store a reference to the context object that contains them. Strategies do not.
24 | States are allowed to replace themselves (IE: to change the state of the context object to something else), while Strategies are not.
25 | Strategies are passed to the context object as parameters, while States are created by the context object itself.
26 | Strategies only handle a single, specific task, while States provide the underlying implementation for everything (or most everything) the context object does.
27 | */
28 |
29 | LegacyTest();
30 | Console.WriteLine();
31 | var gumballmachine = new GumballMachine(5);
32 | gumballmachine.InsertQuarter();
33 | gumballmachine.TurnCrank();
34 | gumballmachine.InsertQuarter();
35 | gumballmachine.TurnCrank();
36 | }
37 |
38 | private static void LegacyTest()
39 | {
40 | var machine = new Legacy.GumballMachine(2);
41 | machine.InsertQuarter();
42 | machine.TurnCrank();
43 | machine.InsertQuarter();
44 | machine.EjectQuarter();
45 | machine.InsertQuarter();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/State/Refactored/Abstraction/IState.cs:
--------------------------------------------------------------------------------
1 | namespace State.Refactored.Abstraction
2 | {
3 | public interface IState
4 | {
5 | void InsertQuarter();
6 | void EjectQuarter();
7 | void TurnCrank();
8 | void Dispense();
9 | }
10 | }
--------------------------------------------------------------------------------
/State/Refactored/StateMachineContext/GumballMachine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using State.Refactored.Abstraction;
3 |
4 | namespace State.Refactored.StateMachineContext
5 | {
6 | public class GumballMachine
7 | {
8 | public int Count { get; private set; }
9 |
10 | public IState SoldOutState;
11 | public IState NoQuarterState;
12 | public IState HasQuarterState;
13 | public IState SoldState;
14 | public IState WinnerState;
15 |
16 | public IState State { get; set; }
17 |
18 | public GumballMachine(int count)
19 | {
20 | Count = count;
21 | SoldOutState = new SoldOutState(this);
22 | NoQuarterState = new NoQuarterState(this);
23 | HasQuarterState = new HasQuarterState(this);
24 | SoldState = new SoldState(this);
25 | WinnerState = new WinnerState(this);
26 | if (Count > 0)
27 | {
28 | State = NoQuarterState;
29 | }
30 | }
31 |
32 | public void InsertQuarter()
33 | {
34 | State.InsertQuarter();
35 | }
36 |
37 | public void EjectQuarter()
38 | {
39 | State.EjectQuarter();
40 | }
41 |
42 | public void TurnCrank()
43 | {
44 | State.TurnCrank();
45 | State.Dispense();
46 | }
47 |
48 | public void ReleaseBall()
49 | {
50 | Console.WriteLine("A ball comes rolling down");
51 | if (Count == 0) return;
52 | Count--;
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/State/Refactored/VariousStates/HasQuarterState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using State.Refactored.Abstraction;
3 | using State.Refactored.StateMachineContext;
4 |
5 | namespace State
6 | {
7 | public class HasQuarterState : IState
8 | {
9 | private GumballMachine Machine { get; }
10 | readonly Random _random = new Random(DateTime.Now.Millisecond);
11 |
12 | public HasQuarterState(GumballMachine gumballMachine)
13 | {
14 | Machine = gumballMachine;
15 | }
16 |
17 | public void InsertQuarter()
18 | {
19 | Console.WriteLine("Can't insert more than one");
20 | }
21 |
22 | public void EjectQuarter()
23 | {
24 | Console.WriteLine("Quarter returned");
25 | Machine.State = Machine.NoQuarterState;
26 | }
27 |
28 | public void TurnCrank()
29 | {
30 | Console.WriteLine("You turned the crank");
31 | var winner = _random.Next(10);
32 | if ((winner == 5) && (Machine.Count > 1))
33 | Machine.State = Machine.WinnerState;
34 | else
35 | {
36 | Machine.State = Machine.SoldState;
37 | }
38 | }
39 |
40 | public void Dispense()
41 | {
42 | Console.WriteLine("Can't do that");
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/State/Refactored/VariousStates/NoQuarterState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using State.Refactored.Abstraction;
3 | using State.Refactored.StateMachineContext;
4 |
5 | namespace State
6 | {
7 | public class NoQuarterState : IState
8 | {
9 | public GumballMachine Machine { get; }
10 |
11 | public NoQuarterState(GumballMachine machine)
12 | {
13 | Machine = machine;
14 | }
15 | public void InsertQuarter()
16 | {
17 | Console.WriteLine("Inserted a quarter");
18 | Machine.State = Machine.HasQuarterState;
19 | }
20 |
21 | public void EjectQuarter()
22 | {
23 | Console.Write("Can't eject anything");
24 | }
25 |
26 | public void TurnCrank()
27 | {
28 | Console.WriteLine("Can't turn crank without a quarter");
29 | }
30 |
31 | public void Dispense()
32 | {
33 | Console.WriteLine("Can't dispense");
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/State/Refactored/VariousStates/SoldOutState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using State.Refactored.Abstraction;
3 | using State.Refactored.StateMachineContext;
4 |
5 | namespace State
6 | {
7 | public class SoldOutState : IState
8 | {
9 | public GumballMachine Machine { get; }
10 |
11 | public SoldOutState(GumballMachine gumballMachine)
12 | {
13 | Machine = gumballMachine;
14 | }
15 |
16 | public void InsertQuarter()
17 | {
18 | Console.WriteLine("Sorry! Sold Out");
19 | }
20 |
21 | public void EjectQuarter()
22 | {
23 | Console.WriteLine("Can't eject when sold out");
24 | }
25 |
26 | public void TurnCrank()
27 | {
28 | Console.WriteLine("turning crank achieves nothing");
29 | }
30 |
31 | public void Dispense()
32 | {
33 | Console.WriteLine("Can't dispense when out of stock");
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/State/Refactored/VariousStates/SoldState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using State.Refactored.Abstraction;
3 | using State.Refactored.StateMachineContext;
4 |
5 | namespace State
6 | {
7 | public class SoldState : IState
8 | {
9 | private GumballMachine Machine { get; }
10 |
11 | public SoldState(GumballMachine gumballMachine)
12 | {
13 | Machine = gumballMachine;
14 | }
15 |
16 | public void InsertQuarter()
17 | {
18 | Console.WriteLine("Please wait, already in progress");
19 | }
20 |
21 | public void EjectQuarter()
22 | {
23 | Console.WriteLine("Can't eject, already turned the crank");
24 | }
25 |
26 | public void TurnCrank()
27 | {
28 | Console.WriteLine("Turning twice achieves nothing");
29 | }
30 |
31 | public void Dispense()
32 | {
33 | Machine.ReleaseBall();
34 | if (Machine.Count > 0)
35 | {
36 | Machine.State = Machine.NoQuarterState;
37 | }
38 | else
39 | {
40 | Console.WriteLine("Oops! No more gumballs");
41 | Machine.State = Machine.SoldOutState;
42 | }
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/State/Refactored/VariousStates/WinnerState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using State.Refactored.Abstraction;
3 | using State.Refactored.StateMachineContext;
4 |
5 | namespace State
6 | {
7 | public class WinnerState : IState
8 | {
9 | private GumballMachine Machine { get; }
10 |
11 | public WinnerState(GumballMachine gumballMachine)
12 | {
13 | Machine = gumballMachine;
14 | }
15 |
16 | public void InsertQuarter()
17 | {
18 | Console.WriteLine("Please wait, already in progress");
19 | }
20 |
21 | public void EjectQuarter()
22 | {
23 | Console.WriteLine("Can't eject, already turned the crank");
24 | }
25 |
26 | public void TurnCrank()
27 | {
28 | Console.WriteLine("Turning twice achieves nothing");
29 | }
30 |
31 |
32 | public void Dispense()
33 | {
34 | Console.WriteLine("You Won!! 2 gumballs for the price of one");
35 | Machine.ReleaseBall();
36 | if (Machine.Count == 0)
37 | {
38 | Machine.State = Machine.SoldOutState;
39 | Console.WriteLine("Oops! No more gumballs");
40 | }
41 | else
42 | {
43 | Machine.ReleaseBall();
44 | Machine.State = Machine.NoQuarterState;
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/State/State.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Strategy/Anbstraction/IDataReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Strategy.Anbstraction
6 | {
7 | public interface IDataReader
8 | {
9 | void ReadData();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Strategy/Implementations/JsonDataReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Strategy.Anbstraction;
5 |
6 | namespace Strategy.Implementations
7 | {
8 | class JsonDataReader:IDataReader
9 | {
10 | public void ReadData()
11 | {
12 | Console.WriteLine("Reading data from json.");
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Strategy/Implementations/SqlDataReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Strategy.Anbstraction;
5 |
6 | namespace Strategy.Implementations
7 | {
8 | class SqlDataReader:IDataReader
9 | {
10 | public void ReadData()
11 | {
12 | Console.WriteLine("Reading data from sql.");
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Strategy/Implementations/XmlDataReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Strategy.Anbstraction;
5 |
6 | namespace Strategy.Implementations
7 | {
8 | class XmlDataReader: IDataReader
9 | {
10 | public void ReadData()
11 | {
12 | Console.WriteLine("Reading data from XML.");
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Strategy/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Strategy.Anbstraction;
4 | using Strategy.Implementations;
5 |
6 | namespace Strategy
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | /*
13 | More info: https://en.wikipedia.org/wiki/Strategy_pattern
14 | http://www.dofactory.com/net/strategy-design-pattern
15 |
16 | What problems can the Strategy design pattern solve? [3]
17 |
18 | A class should be configured with an algorithm instead of implementing an algorithm directly.
19 | An algorithm should be selected and exchanged at run-time.
20 |
21 | What is an algorithm? An algorithm is usually defined as a procedure that takes some value as input,
22 | performs a finite number of steps, and produces some value as output.
23 | From a more general point of view,
24 | an algorithm is a piece of code that does something appropriate.
25 |
26 | Implementing an algorithm directly within the class that uses the algorithm is inflexible because
27 | it commits the class to a particular algorithm at compile-time and makes it impossible to change
28 | the algorithm later independently from (without having to change) the class. This also stops the class
29 | from being reusable when another algorithm should be used.
30 |
31 | */
32 |
33 | var dataReaders = new List { new XmlDataReader(), new JsonDataReader(), new SqlDataReader() };
34 |
35 | //Our client doesn't care how data readers reads data, it only cares that there is a method called *ReadData* which it can call.
36 | foreach (var dataReader in dataReaders)
37 | {
38 | dataReader.ReadData();
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Strategy/Strategy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TemplateMethod/AuditExample/Abstraction/IMessageAuditor.cs:
--------------------------------------------------------------------------------
1 | namespace TemplateMethod.AuditExample.Abstraction
2 | {
3 | public interface IMessageAuditor
4 | {
5 | void Audit(string messageType, string userName, string correlationId, string messageBody);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/TemplateMethod/AuditExample/Abstraction/MessageProcessor.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Principal;
2 | using System.Threading;
3 |
4 | namespace TemplateMethod.AuditExample.Abstraction
5 | {
6 | public abstract class MessageProcessor
7 | {
8 | private readonly IMessageAuditor _auditor;
9 |
10 | public MessageProcessor(IMessageAuditor auditor)
11 | {
12 | _auditor = auditor;
13 | }
14 |
15 | // Template Methods that must be overriden by subclasses
16 |
17 | protected abstract string messageType { get; }
18 |
19 | public void ProcessMessage(Message message)
20 | {
21 | var principal = Thread.CurrentPrincipal;
22 |
23 | if (authorize(message, principal))
24 | {
25 | doWork(message);
26 | audit(message, principal);
27 | }
28 | }
29 |
30 | protected abstract bool authorize(Message message, IPrincipal principal);
31 |
32 | protected abstract void doWork(Message message);
33 |
34 | private void audit(Message message, IPrincipal principal)
35 | {
36 | _auditor.Audit(messageType, principal.Identity.Name, message.CorrelationId, message.Body.ToString());
37 | }
38 | }
39 |
40 | public class Message
41 | {
42 | public string CorrelationId { get; set; }
43 | public object Body { get; set; }
44 | }
45 | }
--------------------------------------------------------------------------------
/TemplateMethod/AuditExample/CancelOrderMessageProcessor.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Principal;
2 | using TemplateMethod.AuditExample.Abstraction;
3 |
4 | namespace TemplateMethod.AuditExample
5 | {
6 | public class CancelOrderMessageProcessor : MessageProcessor
7 |
8 | {
9 | public CancelOrderMessageProcessor(IMessageAuditor auditor) : base(auditor) { }
10 |
11 | protected override string messageType
12 | {
13 | get
14 | {
15 | return "CancelOrder";
16 | }
17 | }
18 |
19 | protected override bool authorize(Message message, IPrincipal principal)
20 | {
21 | // go check whether the IPrincipal user is the same user who placed the order
22 |
23 | // referenced by the contents of the message
24 |
25 | return true;
26 | }
27 |
28 | protected override void doWork(Message message)
29 | {
30 | // find the order number and cancel the order in the backend system
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/TemplateMethod/AuditExample/MoreInfo.txt:
--------------------------------------------------------------------------------
1 | http://codebetter.com/jeremymiller/2006/04/11/six-design-patterns-to-start-with/
2 |
3 | So what have we really accomplished here? For one thing we’ve standardized the message processing.
4 | If we need to handle any new message types we can just create a new subclass and fill in the missing pieces.
5 | Somebody new to the project can create a new message type by following the established pattern.
6 | We’ve also eliminated some code duplication, and that’s always a good thing.
--------------------------------------------------------------------------------
/TemplateMethod/DrinkExample/Abstraction/Beverage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TemplateMethod.DrinkExample.Abstraction
4 | {
5 | public abstract class Beverage
6 | {
7 | protected int _sugar;
8 |
9 | public void Prepare()
10 | {
11 | Boil();
12 | Brew();
13 | Pour();
14 | if (WantsCondiments)
15 | AddCondiments();
16 |
17 | }
18 |
19 | public bool WantsCondiments { private get; set; }
20 |
21 | private void Boil()
22 | {
23 | Console.WriteLine("Boling Water");
24 | }
25 |
26 | protected abstract void Brew();
27 |
28 | private void Pour()
29 | {
30 | Console.WriteLine("Pouring in Cup");
31 | }
32 |
33 | protected abstract void AddCondiments();
34 |
35 | public int AddSugar { get; set; }
36 |
37 | protected void Sugar() { }
38 | }
39 | }
--------------------------------------------------------------------------------
/TemplateMethod/DrinkExample/Implementations/Coffee.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using TemplateMethod.DrinkExample.Abstraction;
3 |
4 | namespace TemplateMethod.DrinkExample.Implementations
5 | {
6 | class Coffee : Beverage
7 | {
8 | protected override void Brew()
9 | {
10 | Console.WriteLine("Add Coffee Grounds to water and boil");
11 | }
12 |
13 | protected override void AddCondiments()
14 | {
15 | Console.WriteLine("Add Milk and Sugar");
16 | }
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/TemplateMethod/DrinkExample/Implementations/Tea.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using TemplateMethod.DrinkExample.Abstraction;
3 |
4 | namespace TemplateMethod.DrinkExample.Implementations
5 | {
6 | class Tea : Beverage
7 | {
8 | protected override void Brew()
9 | {
10 | Console.WriteLine("Adding tea leaves to water and boil");
11 | }
12 |
13 | protected override void AddCondiments()
14 | {
15 | Console.WriteLine("Adding Lemon and Sugar");
16 | Sugar();
17 | }
18 |
19 | private new void Sugar()
20 | {
21 | Console.WriteLine($"adding {_sugar} spoons of sugar");
22 | }
23 |
24 | public new int AddSugar
25 | {
26 | set { _sugar = value; }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/TemplateMethod/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using TemplateMethod.DrinkExample.Implementations;
3 |
4 | namespace TemplateMethod
5 | {
6 | class Program
7 | {
8 | static void Main(string[] args)
9 | {
10 | /*
11 | * More info: https://en.wikipedia.org/wiki/Template_method_pattern
12 | Usage
13 | The template method is used in frameworks, where each implements the invariant parts of a domain's architecture, leaving "placeholders" for customization options.
14 | This is an example of inversion of control. The template method is used for the following reasons:
15 |
16 | Let subclasses implement varying behavior (through method overriding).
17 |
18 | Avoid duplication in the code: the general workflow structure is implemented once in the abstract class's algorithm,
19 | and necessary variations are implemented in the subclasses.
20 |
21 | Control at what point(s) subclassing is allowed. As opposed to a simple polymorphic override,
22 | where the base method would be entirely rewritten allowing radical change to the workflow, only the specific details of the workflow are allowed to change.
23 | */
24 |
25 | var tea = new Tea();
26 |
27 | tea.WantsCondiments = true;
28 | tea.AddSugar = 5;
29 | tea.Prepare();
30 |
31 | Console.WriteLine("====================================================================");
32 |
33 | var coffee = new Coffee();
34 |
35 | coffee.WantsCondiments = true;
36 | coffee.Prepare();
37 |
38 | Console.ReadKey();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/TemplateMethod/TemplateMethod.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Visitor/Elements/BoldText.cs:
--------------------------------------------------------------------------------
1 | using Visitor.ObjectStructure;
2 | using Visitor.Visitors;
3 |
4 | namespace Visitor.Elements
5 | {
6 | public class BoldText : DocumentPart
7 | {
8 | public override void Accept(IVisitor visitor)
9 | {
10 | visitor.Visit(this);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Visitor/Elements/Hyperlink.cs:
--------------------------------------------------------------------------------
1 | using Visitor.ObjectStructure;
2 | using Visitor.Visitors;
3 |
4 | namespace Visitor.Elements
5 | {
6 | public class Hyperlink : DocumentPart
7 | {
8 | public string Url { get; set; }
9 |
10 | public override void Accept(IVisitor visitor)
11 | {
12 | visitor.Visit(this);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Visitor/Elements/PlainText.cs:
--------------------------------------------------------------------------------
1 | using Visitor.ObjectStructure;
2 | using Visitor.Visitors;
3 |
4 | namespace Visitor.Elements
5 | {
6 | public class PlainText : DocumentPart
7 | {
8 | public override void Accept(IVisitor visitor)
9 | {
10 | visitor.Visit(this);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Visitor/ObjectStructure/Document.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Visitor.Visitors;
3 |
4 | namespace Visitor.ObjectStructure
5 | {
6 | public class Document
7 | {
8 | private readonly List _mParts;
9 |
10 | public Document(params DocumentPart[] documents)
11 | {
12 | _mParts = new List();
13 | _mParts.AddRange(documents);
14 | }
15 |
16 | public void Accept(IVisitor visitor)
17 | {
18 | foreach (DocumentPart part in this._mParts) part.Accept(visitor);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Visitor/ObjectStructure/DocumentPart.cs:
--------------------------------------------------------------------------------
1 | using Visitor.Visitors;
2 |
3 | namespace Visitor.ObjectStructure
4 | {
5 | public abstract class DocumentPart
6 | {
7 | public string Text { get; set; }
8 | public abstract void Accept(IVisitor visitor);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Visitor/OldImplementation/OldImplementation.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace OldImplementation
4 | {
5 | public abstract class DocumentPart
6 | {
7 | public string Text { get; private set; }
8 | public abstract string ToHTML();
9 | public abstract string ToPlainText();
10 | public abstract string ToLatex();
11 | }
12 |
13 | public class PlainText : DocumentPart
14 | {
15 | public override string ToHTML()
16 | {
17 | return this.Text;
18 | }
19 | public override string ToPlainText()
20 | {
21 | return this.Text;
22 | }
23 | public override string ToLatex()
24 | {
25 | return this.Text;
26 | }
27 | }
28 |
29 | public class BoldText : DocumentPart
30 | {
31 | public override string ToHTML()
32 | {
33 | return "" + this.Text + "";
34 | }
35 | public override string ToPlainText()
36 | {
37 | return "**" + this.Text + "**";
38 | }
39 | public override string ToLatex()
40 | {
41 | return "\\textbf{" + this.Text + "}";
42 | }
43 | }
44 |
45 | public class Hyperlink : DocumentPart
46 | {
47 | public string Url { get; private set; }
48 |
49 | public override string ToHTML()
50 | {
51 | return "" + this.Text + "";
52 | }
53 | public override string ToPlainText()
54 | {
55 | return this.Text + " [" + this.Url + "]";
56 | }
57 | public override string ToLatex()
58 | {
59 | return "\\href{" + this.Url + "}{" + this.Text + "}";
60 | }
61 | }
62 |
63 | public class Document
64 | {
65 | private List m_parts;
66 |
67 | public string ToHTML()
68 | {
69 | string output = "";
70 | foreach (DocumentPart part in this.m_parts)
71 | {
72 | output += part.ToHTML();
73 | }
74 | return output;
75 | }
76 |
77 | public string ToPlainText()
78 | {
79 | string output = "";
80 | foreach (DocumentPart part in this.m_parts)
81 | {
82 | output += part.ToPlainText();
83 | }
84 | return output;
85 | }
86 |
87 | public string ToLatex()
88 | {
89 | string output = "";
90 | foreach (DocumentPart part in this.m_parts)
91 | {
92 | output += part.ToLatex();
93 | }
94 | return output;
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Visitor/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Visitor.Elements;
3 | using Visitor.ObjectStructure;
4 | using Visitor.Visitors;
5 |
6 | namespace Visitor
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | /*
13 | More info: https://manski.net/2013/05/the-visitor-pattern-explained
14 | What problems can the Visitor design pattern solve?
15 |
16 | It should be possible to define a new operation for (some) classe
17 | s of an object structure without changing the classes.
18 |
19 | When new operations are needed frequently and the object structure consists of many unrelated classes,
20 | it's inflexible to add new subclasses each time a new operation is required because "[..] distributing
21 | all these operations across the various node classes leads to a system that's hard to understand, maintain, and change."
22 |
23 | */
24 |
25 | var doc = new Document(new PlainText { Text = "Plain" }, new Hyperlink { Text = "Hyper", Url = "Link" });
26 | var visitor = new HtmlVisitor();
27 | doc.Accept(visitor);
28 | Console.WriteLine($"Plain text plus Hyperlink {visitor.Output}");
29 |
30 | var doc2 = new Document(new PlainText { Text = "Plain" }, new Hyperlink { Text = "Hyper", Url = "Link" });
31 | var visitor2 = new LatexVisitor();
32 | doc.Accept(visitor);
33 | Console.WriteLine($"Plain text plus Hyperlink {visitor.Output}");
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Visitor/Visitor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Visitor/Visitors/HtmlVisitor.cs:
--------------------------------------------------------------------------------
1 | using Visitor.Elements;
2 |
3 | namespace Visitor.Visitors
4 | {
5 | public class HtmlVisitor : IVisitor
6 | {
7 | public string Output
8 | {
9 | get { return this.m_output; }
10 | set { this.m_output = value; }
11 | }
12 |
13 | private string m_output = "";
14 |
15 | public void Visit(PlainText docPart)
16 | {
17 | this.m_output += docPart.Text;
18 | }
19 |
20 | public void Visit(BoldText docPart)
21 | {
22 | this.m_output += "" + docPart.Text + "";
23 | }
24 |
25 | public void Visit(Hyperlink docPart)
26 | {
27 | this.m_output += "" + docPart.Text + "";
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Visitor/Visitors/IVisitor.cs:
--------------------------------------------------------------------------------
1 | using Visitor.Elements;
2 |
3 | namespace Visitor.Visitors
4 | {
5 | public interface IVisitor
6 | {
7 | void Visit(PlainText docPart);
8 | void Visit(BoldText docPart);
9 | void Visit(Hyperlink docPart);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Visitor/Visitors/LatexVisitor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Visitor.Elements;
5 |
6 | namespace Visitor.Visitors
7 | {
8 | public class LatexVisitor : IVisitor
9 | {
10 | public string Output
11 | {
12 | get { return this.m_output; }
13 | }
14 | private string m_output = "";
15 |
16 | public void Visit(PlainText docPart)
17 | {
18 | this.m_output += docPart.Text;
19 | }
20 |
21 | public void Visit(BoldText docPart)
22 | {
23 | this.m_output += "\\textbf{" + docPart.Text + "}";
24 | }
25 |
26 | public void Visit(Hyperlink docPart)
27 | {
28 | this.m_output += "\\href{" + docPart.Url + "}{" + docPart.Text + "}";
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------