diff --git a/158.326 Software Architecture.sln b/158.326 Software Architecture.sln
index de24ede..fb345a2 100644
--- a/158.326 Software Architecture.sln
+++ b/158.326 Software Architecture.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.31515.178
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31710.8
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "158326 Week 7 Singletons", "158326 Week 7 Singletons\158326 Week 7 Singletons.csproj", "{DDB32161-79F3-4CCF-9CCC-44CCD562B15E}"
EndProject
@@ -23,6 +23,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tutorial 5", "Tutorial 5\Tu
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tutorial 6", "Tutorial 6\Tutorial 6.csproj", "{00702453-3AD5-4822-A38C-2859B52C3E4C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tutorial 9", "Tutorial 9\Tutorial 9.csproj", "{38781F4C-0A86-42F7-8912-D17CF5E0FDED}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tutorial 9 Tests", "Tutorial 9 Tests\Tutorial 9 Tests.csproj", "{5198ABA9-CBE2-4AEF-95D5-F14705697294}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -69,6 +73,14 @@ Global
{00702453-3AD5-4822-A38C-2859B52C3E4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00702453-3AD5-4822-A38C-2859B52C3E4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00702453-3AD5-4822-A38C-2859B52C3E4C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {38781F4C-0A86-42F7-8912-D17CF5E0FDED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {38781F4C-0A86-42F7-8912-D17CF5E0FDED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {38781F4C-0A86-42F7-8912-D17CF5E0FDED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {38781F4C-0A86-42F7-8912-D17CF5E0FDED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5198ABA9-CBE2-4AEF-95D5-F14705697294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5198ABA9-CBE2-4AEF-95D5-F14705697294}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5198ABA9-CBE2-4AEF-95D5-F14705697294}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5198ABA9-CBE2-4AEF-95D5-F14705697294}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/158326 Week 7 Singletons/Program.cs b/158326 Week 7 Singletons/Program.cs
index 0630e10..d350ee4 100644
--- a/158326 Week 7 Singletons/Program.cs
+++ b/158326 Week 7 Singletons/Program.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
namespace _158326_Week_7_Singletons
@@ -10,6 +11,58 @@ namespace _158326_Week_7_Singletons
Console.WriteLine("158.326 Software Architecture");
Console.WriteLine("\tWeek 7 - Singleton Design Pattern");
Console.WriteLine("\tSingletons are instanced classes that can have only 0 or 1 instances of that class in existance in the application (Multitons are a variant that restricts the maximum number of instances)");
+ Console.WriteLine("\nCompany:");
+ for (int i = 0; i < 10; i++)
+ {
+ try
+ {
+ Company instanceOfCompany = Company.GetCompany();
+ Console.WriteLine(instanceOfCompany.ShowDetails());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+ Console.WriteLine("\nFileSingleton:");
+ for (int i = 0; i < 10; i++)
+ {
+ try
+ {
+ FileSingleton instanceOfCompany = FileSingleton.GetInstance(i);
+ Console.WriteLine(instanceOfCompany.ShowDetails());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+ for (int i = 100; i < 110; i++)
+ {
+ try
+ {
+ FileSingleton instanceOfCompany = FileSingleton.GetInstance(i);
+ Console.WriteLine(instanceOfCompany.ShowDetails());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+ Console.WriteLine("\nCompany:");
+ for (int i = 0; i < 10; i++)
+ {
+ try
+ {
+ Company instanceOfCompany = Company.GetCompany();
+ Console.WriteLine(instanceOfCompany.ShowDetails());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+
}
}
@@ -23,14 +76,15 @@ namespace _158326_Week_7_Singletons
/// Store the instance in a private, static variable
///
private static FileSingleton instance;
+ private string _name;
///
/// Path of the file to open
///
- public static Uri FilePath { get; set; } = new Uri("\\log.txt", UriKind.Relative); // Opens exactly one file stream on log.txt and will always return that stream
+ //public static Uri FilePath { get; set; } = new Uri("\\log.txt", UriKind.Relative); // Opens exactly one file stream on log.txt and will always return that stream
// We can define instance variables here:
- public FileStream OpenedFileStream { get; set; } // Calling FileSingleton.GetInstance().OpenedFileStream will always return this object
+ // public FileStream OpenedFileStream { get; set; } // Calling FileSingleton.GetInstance().OpenedFileStream will always return this object
// We can also define
@@ -40,20 +94,68 @@ namespace _158326_Week_7_Singletons
/// This restricts the creation of this instance to local methods, so by restricting constructor calls
/// to GetInstance(), we can ensure that only one instance is created
///
- private FileSingleton() { }
+ private FileSingleton(int i)
+ {
+ _name = i.ToString();
+ }
///
/// Gets the initialised instance of FileSingleton
///
///
- public static FileSingleton GetInstance()
+public static FileSingleton GetInstance(int i)
+{
+ if (instance is null)
+ {
+ instance = new FileSingleton(i);
+ }
+ return instance;
+}
+
+ public string ShowDetails()
{
- if (instance is null)
+ return _name;
+ }
+ }
+
+ public sealed class Company
+ {
+ private string _name;
+ private static Company _company;
+ private bool _legalInstance;
+ private List _listEmployee;
+
+ private Company()
+ {
+ if (_company == null)
{
- instance = new FileSingleton();
+ _company = this;
+ _name = "test";
+ _legalInstance = true;
+ }
+ else
+ {
+ _legalInstance = false;
+ }
+
+ }
+
+ public static Company GetCompany()
+ {
+ return new Company();
+ }
+
+ public string ShowDetails()
+ {
+ if (_legalInstance)
+ {
+ return _name;
+ }
+ else
+ {
+ throw new ApplicationException("Null Object");
}
- return instance;
}
}
}
diff --git a/Tutorial 5/CurrentConditionsDisplay.cs b/Tutorial 5/CurrentConditionsDisplay.cs
index 72d2a2b..a10b417 100644
--- a/Tutorial 5/CurrentConditionsDisplay.cs
+++ b/Tutorial 5/CurrentConditionsDisplay.cs
@@ -13,13 +13,20 @@ namespace Tutorial_5
public partial class CurrentConditionsDisplay : Form, IWeatherObserver, IDisplay
{
ISubject subject;
- WeatherData weatherData;
+ //WeatherData_old weatherData;
private void RegisterButton_Click(object sender, EventArgs e)
{
subject.RegisterObserver(this);
}
double temperature = default, humidity = default, pressure = default;
+
+ ///
+ /// Push technique
+ ///
+ ///
+ ///
+ ///
public void Update(double temperature, double humidity, double pressure)
{
this.temperature = temperature;
@@ -30,9 +37,9 @@ namespace Tutorial_5
public void UpdateOther()
{
- this.temperature = weatherData.GetTemperature();
- this.humidity = weatherData.GetHumidity();
- this.pressure = weatherData.GetPressure();
+ //this.temperature = weatherData.GetTemperature();
+ //this.humidity = weatherData.GetHumidity();
+ //this.pressure = weatherData.GetPressure();
}
public void Display()
diff --git a/Tutorial 5/ForecastDisplay.Designer.cs b/Tutorial 5/ForecastDisplay.Designer.cs
new file mode 100644
index 0000000..8e5a737
--- /dev/null
+++ b/Tutorial 5/ForecastDisplay.Designer.cs
@@ -0,0 +1,98 @@
+
+namespace Tutorial_5
+{
+ partial class ForecastDisplay
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.ConditionLabel = new System.Windows.Forms.Label();
+ this.RegisterButton = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label1.Location = new System.Drawing.Point(100, 9);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(96, 26);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Forecast";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(14, 106);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(104, 13);
+ this.label2.TabIndex = 1;
+ this.label2.Text = "Expected Conditions";
+ //
+ // ConditionLabel
+ //
+ this.ConditionLabel.AutoSize = true;
+ this.ConditionLabel.Location = new System.Drawing.Point(124, 106);
+ this.ConditionLabel.Name = "ConditionLabel";
+ this.ConditionLabel.Size = new System.Drawing.Size(139, 13);
+ this.ConditionLabel.TabIndex = 2;
+ this.ConditionLabel.Text = "______________________";
+ //
+ // RegisterButton
+ //
+ this.RegisterButton.Location = new System.Drawing.Point(85, 231);
+ this.RegisterButton.Name = "RegisterButton";
+ this.RegisterButton.Size = new System.Drawing.Size(136, 23);
+ this.RegisterButton.TabIndex = 3;
+ this.RegisterButton.Text = "Register Observer";
+ this.RegisterButton.UseVisualStyleBackColor = true;
+ //
+ // ForecastDisplay
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(304, 450);
+ this.Controls.Add(this.RegisterButton);
+ this.Controls.Add(this.ConditionLabel);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.label1);
+ this.Name = "ForecastDisplay";
+ this.Text = "ForecastDisplay";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label ConditionLabel;
+ private System.Windows.Forms.Button RegisterButton;
+ }
+}
\ No newline at end of file
diff --git a/Tutorial 5/ForecastDisplay.cs b/Tutorial 5/ForecastDisplay.cs
new file mode 100644
index 0000000..c5c926f
--- /dev/null
+++ b/Tutorial 5/ForecastDisplay.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Tutorial_5
+{
+ public partial class ForecastDisplay : Form
+ {
+ public ForecastDisplay()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Tutorial 5/Form1.resx b/Tutorial 5/ForecastDisplay.resx
similarity index 100%
rename from Tutorial 5/Form1.resx
rename to Tutorial 5/ForecastDisplay.resx
diff --git a/Tutorial 5/Form1.cs b/Tutorial 5/Form1.cs
deleted file mode 100644
index 505320d..0000000
--- a/Tutorial 5/Form1.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-
-namespace Tutorial_5
-{
- public partial class Form1 : Form
- {
- ISubject subject;
- public Form1()
- {
- InitializeComponent();
- this.subject = new WeatherData();
-
-
- }
-
- private void Form1_Load(object sender, EventArgs e)
- {
-
- }
-
- private void SliderChanged(object sender, EventArgs e)
- {
- subject.NotifyObservers();
- TemperatureLabel.Text = TemperatureSlider.Value.ToString() + " ℃";
- HumidityLabel.Text = HumiditySlider.Value.ToString() + " %";
- PressureLabel.Text = PressureSlider.Value.ToString() + " kPa";
- }
-
- private void Form1_Load_1(object sender, EventArgs e)
- {
- CurrentConditionsDisplay ccd = new CurrentConditionsDisplay(this.subject);
- ccd.Show();
- }
- }
-}
diff --git a/Tutorial 5/Program.cs b/Tutorial 5/Program.cs
index a69b8c9..c316cd1 100644
--- a/Tutorial 5/Program.cs
+++ b/Tutorial 5/Program.cs
@@ -16,7 +16,7 @@ namespace Tutorial_5
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new Form1());
+ Application.Run(new WeatherData());
}
}
diff --git a/Tutorial 5/Tutorial 5.csproj b/Tutorial 5/Tutorial 5.csproj
index cb9e440..8f10130 100644
--- a/Tutorial 5/Tutorial 5.csproj
+++ b/Tutorial 5/Tutorial 5.csproj
@@ -51,11 +51,17 @@
CurrentConditionsDisplay.cs
-
+
Form
-
- Form1.cs
+
+ ForecastDisplay.cs
+
+
+ Form
+
+
+ WeatherData.cs
@@ -63,12 +69,14 @@
-
CurrentConditionsDisplay.cs
-
- Form1.cs
+
+ ForecastDisplay.cs
+
+
+ WeatherData.cs
ResXFileCodeGenerator
diff --git a/Tutorial 5/Form1.Designer.cs b/Tutorial 5/WeatherData.Designer.cs
similarity index 99%
rename from Tutorial 5/Form1.Designer.cs
rename to Tutorial 5/WeatherData.Designer.cs
index a682f29..b94ddf5 100644
--- a/Tutorial 5/Form1.Designer.cs
+++ b/Tutorial 5/WeatherData.Designer.cs
@@ -1,7 +1,7 @@
namespace Tutorial_5
{
- partial class Form1
+ partial class WeatherData
{
///
/// Required designer variable.
diff --git a/Tutorial 5/WeatherData.cs b/Tutorial 5/WeatherData.cs
index 89de336..29aa6ba 100644
--- a/Tutorial 5/WeatherData.cs
+++ b/Tutorial 5/WeatherData.cs
@@ -1,12 +1,16 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows.Forms;
namespace Tutorial_5
{
- class WeatherData : ISubject
+ public partial class WeatherData : Form, ISubject
{
List observers;
public void DeregisterObserver(IWeatherObserver observer)
@@ -15,6 +19,9 @@ namespace Tutorial_5
else Console.Error.WriteLine("{0} does not exist in the observers list.", observer.ToString());
}
+ ///
+ /// 'Push' method
+ ///
public void NotifyObservers()
{
double t = GetTemperature();
@@ -23,7 +30,7 @@ namespace Tutorial_5
foreach (var observer in observers)
{
- observer.Update(t,h,p);
+ observer.Update(t, h, p);
}
}
@@ -35,17 +42,17 @@ namespace Tutorial_5
public double GetTemperature()
{
- return 0.0;
+ return TemperatureSlider.Value;
}
public double GetHumidity()
{
- return 0.0;
+ return HumiditySlider.Value;
}
public double GetPressure()
{
- return 0.0;
+ return PressureSlider.Value;
}
void MeasurementChanged()
@@ -55,7 +62,33 @@ namespace Tutorial_5
public WeatherData()
{
+ InitializeComponent();
observers = new List();
}
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ ///
+ /// Analagous to the Update() method in Excercise 1
+ /// Pushes data to observers via Subject.NotifyObservers
+ ///
+ ///
+ ///
+ private void SliderChanged(object sender, EventArgs e)
+ {
+ NotifyObservers();
+ TemperatureLabel.Text = TemperatureSlider.Value.ToString() + " ℃";
+ HumidityLabel.Text = HumiditySlider.Value.ToString() + " %";
+ PressureLabel.Text = PressureSlider.Value.ToString() + " kPa";
+ }
+
+ private void Form1_Load_1(object sender, EventArgs e)
+ {
+ CurrentConditionsDisplay ccd = new CurrentConditionsDisplay(this);
+ ccd.Show();
+ }
}
}
diff --git a/Tutorial 5/WeatherData.resx b/Tutorial 5/WeatherData.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/Tutorial 5/WeatherData.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Tutorial 9 Tests/Properties/AssemblyInfo.cs b/Tutorial 9 Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..3c6c916
--- /dev/null
+++ b/Tutorial 9 Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,20 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tutorial 9 Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tutorial 9 Tests")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("5198aba9-cbe2-4aef-95d5-f14705697294")]
+
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tutorial 9 Tests/Tutorial 9 Tests.csproj b/Tutorial 9 Tests/Tutorial 9 Tests.csproj
new file mode 100644
index 0000000..b5f70bb
--- /dev/null
+++ b/Tutorial 9 Tests/Tutorial 9 Tests.csproj
@@ -0,0 +1,74 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+ {5198ABA9-CBE2-4AEF-95D5-F14705697294}
+ Library
+ Properties
+ Tutorial_9_Tests
+ Tutorial 9 Tests
+ v4.7.2
+ 512
+ {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 15.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+ $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
+ False
+ UnitTest
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
+
+
+ ..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {38781f4c-0a86-42f7-8912-d17cf5e0fded}
+ Tutorial 9
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tutorial 9 Tests/UnitTest1.cs b/Tutorial 9 Tests/UnitTest1.cs
new file mode 100644
index 0000000..61c4d15
--- /dev/null
+++ b/Tutorial 9 Tests/UnitTest1.cs
@@ -0,0 +1,28 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using Tutorial_9;
+
+namespace Tutorial_9_Tests
+{
+ [TestClass]
+ public class UnitTest1
+ {
+ [TestMethod]
+ public void SedanNoDiscountTest()
+ {
+ Sedan sedan = new Sedan();
+ Assert.AreEqual(0, sedan.PriceAfterDays(0));
+ Assert.AreEqual(80, sedan.PriceAfterDays(1));
+ Assert.AreEqual(320, sedan.PriceAfterDays(4));
+ }
+
+ [TestMethod]
+ public void TestCarTest()
+ {
+ TestCar sedan = new TestCar();
+ Assert.AreEqual(0, sedan.PriceAfterDays(0));
+ Assert.AreEqual(0, sedan.PriceAfterDays(1));
+ Assert.AreEqual(0, sedan.PriceAfterDays(4));
+ }
+ }
+}
diff --git a/Tutorial 9 Tests/packages.config b/Tutorial 9 Tests/packages.config
new file mode 100644
index 0000000..f84cb10
--- /dev/null
+++ b/Tutorial 9 Tests/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Tutorial 9/Properties/AssemblyInfo.cs b/Tutorial 9/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..836e892
--- /dev/null
+++ b/Tutorial 9/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Tutorial 9")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tutorial 9")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("38781f4c-0a86-42f7-8912-d17cf5e0fded")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tutorial 9/Rental.cs b/Tutorial 9/Rental.cs
new file mode 100644
index 0000000..e4fd94f
--- /dev/null
+++ b/Tutorial 9/Rental.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tutorial_9
+{
+ public abstract class Car
+ {
+ protected abstract decimal Price { get; }
+ public decimal PriceAfterDays(decimal numDays)
+ {
+ decimal result;
+ if (numDays < 0 || numDays >= 90) throw new ArgumentOutOfRangeException("Provided number of days is invalid");
+ if (numDays < 5)
+ {
+ result = Price * numDays;
+ }
+ else if (numDays < 10)
+ {
+ result = Price * numDays * 0.9M;
+ }
+ else if (numDays < 20)
+ {
+ result = Price * numDays * 0.85M;
+ }
+ else
+ {
+ result = Price * numDays * 0.8M;
+ }
+ return result;
+ }
+ }
+
+ public class Hatchback : Car
+ {
+ protected override decimal Price => 50;
+ }
+
+ public class Sedan : Car
+ {
+ protected override decimal Price => 80;
+ }
+
+ public class Convertible : Car
+ {
+ protected override decimal Price => 100;
+ }
+
+ public class Saloon : Car
+ {
+ protected override decimal Price => 120;
+ }
+ public class Motorcycle : Car
+ {
+ protected override decimal Price => 20;
+ }
+}
diff --git a/Tutorial 9/Tutorial 9.csproj b/Tutorial 9/Tutorial 9.csproj
new file mode 100644
index 0000000..7feea4f
--- /dev/null
+++ b/Tutorial 9/Tutorial 9.csproj
@@ -0,0 +1,48 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {38781F4C-0A86-42F7-8912-D17CF5E0FDED}
+ Library
+ Properties
+ Tutorial_9
+ Tutorial 9
+ v4.7.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file