diff --git a/BehavioralPatterns.sln b/BehavioralPatterns.sln
new file mode 100644
index 0000000..bf2c943
--- /dev/null
+++ b/BehavioralPatterns.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25123.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3820200F-354C-41E6-8F34-B301F5D621C2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4780CECA-2B6F-4F79-97C5-D1B483CFC881}"
+ ProjectSection(SolutionItems) = preProject
+ global.json = global.json
+ EndProjectSection
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BehavioralPatterns", "src\BehavioralPatterns\BehavioralPatterns.xproj", "{E3092EE0-1282-4AB4-9FA2-0338348D8FD1}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ChainOfResponssibility", "src\ChainOfResponssibility\ChainOfResponssibility.xproj", "{89536824-683F-4351-8789-406D7BDD922D}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CommandPattern", "src\CommandPattern\CommandPattern.xproj", "{CCC23C3A-7A67-40BD-80FB-C4D2C0342E50}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {89536824-683F-4351-8789-406D7BDD922D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {89536824-683F-4351-8789-406D7BDD922D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {89536824-683F-4351-8789-406D7BDD922D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {89536824-683F-4351-8789-406D7BDD922D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CCC23C3A-7A67-40BD-80FB-C4D2C0342E50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CCC23C3A-7A67-40BD-80FB-C4D2C0342E50}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CCC23C3A-7A67-40BD-80FB-C4D2C0342E50}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CCC23C3A-7A67-40BD-80FB-C4D2C0342E50}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {E3092EE0-1282-4AB4-9FA2-0338348D8FD1} = {3820200F-354C-41E6-8F34-B301F5D621C2}
+ {89536824-683F-4351-8789-406D7BDD922D} = {3820200F-354C-41E6-8F34-B301F5D621C2}
+ {CCC23C3A-7A67-40BD-80FB-C4D2C0342E50} = {3820200F-354C-41E6-8F34-B301F5D621C2}
+ EndGlobalSection
+EndGlobal
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..b51e28b
--- /dev/null
+++ b/global.json
@@ -0,0 +1,6 @@
+{
+ "projects": [ "src", "test" ],
+ "sdk": {
+ "version": "1.0.0-preview1-002702"
+ }
+}
diff --git a/src/BehavioralPatterns/BehavioralPatterns.xproj b/src/BehavioralPatterns/BehavioralPatterns.xproj
new file mode 100644
index 0000000..7cf4f9e
--- /dev/null
+++ b/src/BehavioralPatterns/BehavioralPatterns.xproj
@@ -0,0 +1,21 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ e3092ee0-1282-4ab4-9fa2-0338348d8fd1
+ BehavioralPatterns
+ .\obj
+ .\bin\
+ v4.6.1
+
+
+
+ 2.0
+
+
+
diff --git a/src/BehavioralPatterns/Program.cs b/src/BehavioralPatterns/Program.cs
new file mode 100644
index 0000000..a8c7f30
--- /dev/null
+++ b/src/BehavioralPatterns/Program.cs
@@ -0,0 +1,21 @@
+using ChainOfResponssibility;
+using ChainOfResponssibility.PurchaseExample;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace BehavioralPatterns
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ //Chain of responsibillity
+ //This is usefull when you have a request and you don't know who should process it
+ ChainOfResponsibillityExamples.Run();
+ Console.ReadKey();
+ }
+ }
+}
diff --git a/src/BehavioralPatterns/Properties/AssemblyInfo.cs b/src/BehavioralPatterns/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..42755e8
--- /dev/null
+++ b/src/BehavioralPatterns/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+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: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Hewlett-Packard Company")]
+[assembly: AssemblyProduct("BehavioralPatterns")]
+[assembly: AssemblyTrademark("")]
+
+// 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("e3092ee0-1282-4ab4-9fa2-0338348d8fd1")]
diff --git a/src/BehavioralPatterns/project.json b/src/BehavioralPatterns/project.json
new file mode 100644
index 0000000..f111bfd
--- /dev/null
+++ b/src/BehavioralPatterns/project.json
@@ -0,0 +1,20 @@
+{
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "emitEntryPoint": true
+ },
+
+ "dependencies": {
+ "ChainOfResponssibility": "1.0.0-*",
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0-rc2-3002702"
+ }
+ },
+
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": "dnxcore50"
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/ChainOfResponssibility.xproj b/src/ChainOfResponssibility/ChainOfResponssibility.xproj
new file mode 100644
index 0000000..a16e95e
--- /dev/null
+++ b/src/ChainOfResponssibility/ChainOfResponssibility.xproj
@@ -0,0 +1,21 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ 89536824-683f-4351-8789-406d7bdd922d
+ ChainOfResponssibility
+ .\obj
+ .\bin\
+ v4.6.1
+
+
+
+ 2.0
+
+
+
diff --git a/src/ChainOfResponssibility/Properties/AssemblyInfo.cs b/src/ChainOfResponssibility/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0d80bcf
--- /dev/null
+++ b/src/ChainOfResponssibility/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+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: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Hewlett-Packard Company")]
+[assembly: AssemblyProduct("ChainOfResponssibility")]
+[assembly: AssemblyTrademark("")]
+
+// 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("89536824-683f-4351-8789-406d7bdd922d")]
diff --git a/src/ChainOfResponssibility/PurchaseExample/CheckAuthority.cs b/src/ChainOfResponssibility/PurchaseExample/CheckAuthority.cs
new file mode 100644
index 0000000..51a9c3b
--- /dev/null
+++ b/src/ChainOfResponssibility/PurchaseExample/CheckAuthority.cs
@@ -0,0 +1,92 @@
+using System;
+
+namespace ChainOfResponssibility.PurchaseExample
+{
+ public class CheckAuthority
+ {
+ ManagerPPower manager;
+ DirectorPPower director;
+ VicePresidentPPower vp;
+ PresidentPPower president;
+
+ public CheckAuthority()
+ {
+ manager = new ManagerPPower();
+ director = new DirectorPPower();
+ vp = new VicePresidentPPower();
+ president = new PresidentPPower();
+
+ manager.Successor = director;
+ director.Successor = vp;
+ vp.Successor = president;
+ }
+
+ public void PrintHowMuchEachCanSpend()
+ {
+ manager.PrintHowMuchICanSpend();
+ director.PrintHowMuchICanSpend();
+ vp.PrintHowMuchICanSpend();
+ president.PrintHowMuchICanSpend();
+ }
+
+ public void SpendMoney()
+ {
+ string input = "";
+ do
+ {
+ Console.WriteLine("Enter the amount to check who should approve your expenditure.");
+ Console.Write(">");
+ input = Console.ReadLine();
+
+ if (IsDoulbe(input))
+ {
+ double d = double.Parse(input);
+ manager.ProcessRequest(new PurchaseRequest(d, "I am beautifull"));
+ }
+
+ } while (!IsExitCode(input));
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ private static bool IsExitCode(string input)
+ {
+ return "exit".Equals(input, StringComparison.OrdinalIgnoreCase);
+ }
+
+ private bool IsDoulbe(string input)
+ {
+ double x = 0;
+ return double.TryParse(input, out x);
+ }
+
+
+ public string GetDescriptionOfClass()
+ {
+ return @"CheckAuthority allows an employee to spend money
+ if(manager can approve it) manager will process the request
+ if (director can approve it) director will process the request
+ if (vice president can approve it) vice president will process the request
+ if (president can approve it) president will process the request";
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/PurchaseExample/PurchasePower.cs b/src/ChainOfResponssibility/PurchaseExample/PurchasePower.cs
new file mode 100644
index 0000000..4efa410
--- /dev/null
+++ b/src/ChainOfResponssibility/PurchaseExample/PurchasePower.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.PurchaseExample
+{
+ public abstract class PurchasePower
+ {
+ protected const double BaseUnit = 500;
+
+ public PurchasePower Successor { get; set; }
+
+ protected abstract double MaximumToSpend { get; }
+
+ protected abstract string Role { get; }
+
+ public void ProcessRequest(PurchaseRequest request)
+ {
+ if (request.Ammount <= MaximumToSpend)
+ {
+ Console.WriteLine("{0} will approve ${1}", Role, request.Ammount);
+ }
+ else
+ {
+ if (Successor != null)
+ Successor.ProcessRequest(request);
+ else
+ Console.WriteLine("No one has that much money");
+ }
+ }
+
+ public void PrintHowMuchICanSpend()
+ {
+ Console.WriteLine("As a {0} I can spend at most {1}", Role, MaximumToSpend);
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/PurchaseExample/PurchasePowerClasses.cs b/src/ChainOfResponssibility/PurchaseExample/PurchasePowerClasses.cs
new file mode 100644
index 0000000..e56060e
--- /dev/null
+++ b/src/ChainOfResponssibility/PurchaseExample/PurchasePowerClasses.cs
@@ -0,0 +1,30 @@
+namespace ChainOfResponssibility.PurchaseExample
+{
+ public class ManagerPPower : PurchasePower
+ {
+ protected override double MaximumToSpend { get { return BaseUnit * 10; } }
+
+ protected override string Role { get { return "Manager"; } }
+ }
+
+ public class DirectorPPower : PurchasePower
+ {
+ protected override double MaximumToSpend { get { return BaseUnit * 20; } }
+
+ protected override string Role { get { return "Director"; } }
+ }
+
+ public class VicePresidentPPower : PurchasePower
+ {
+ protected override double MaximumToSpend { get { return BaseUnit * 40; } }
+
+ protected override string Role { get { return "VicePresident"; } }
+ }
+
+ public class PresidentPPower : PurchasePower
+ {
+ protected override double MaximumToSpend { get { return BaseUnit * 60; } }
+
+ protected override string Role { get { return "President"; } }
+ }
+}
diff --git a/src/ChainOfResponssibility/PurchaseExample/PurchaseRequest.cs b/src/ChainOfResponssibility/PurchaseExample/PurchaseRequest.cs
new file mode 100644
index 0000000..532f2c9
--- /dev/null
+++ b/src/ChainOfResponssibility/PurchaseExample/PurchaseRequest.cs
@@ -0,0 +1,16 @@
+namespace ChainOfResponssibility.PurchaseExample
+{
+ public class PurchaseRequest
+ {
+ public PurchaseRequest(double ammount, string reason)
+ {
+ Ammount = ammount;
+
+ Reason = reason;
+ }
+
+ public double Ammount { get; private set; }
+
+ public string Reason { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/ChainOfResponssibility/RunChainOfResponsibillityExamples.cs b/src/ChainOfResponssibility/RunChainOfResponsibillityExamples.cs
new file mode 100644
index 0000000..6c28c10
--- /dev/null
+++ b/src/ChainOfResponssibility/RunChainOfResponsibillityExamples.cs
@@ -0,0 +1,91 @@
+using ChainOfResponssibility.PurchaseExample;
+using ChainOfResponssibility.TransferFileExample;
+using ChainOfResponssibility.Validators.UserEntities;
+using System;
+
+namespace ChainOfResponssibility
+{
+ public class ChainOfResponsibillityExamples
+ {
+ public static void Run()
+ {
+ Console.WriteLine(GetPatternDescription());
+ GoToNextStep();
+
+ Console.WriteLine(ExeucteFirstWhenConditionMatchesFlavorDescription());
+ GoToNextStep();
+
+ CheckAuthority moneySpender = new CheckAuthority();
+
+ Console.WriteLine(moneySpender.GetDescriptionOfClass());
+ GoToNextStep();
+
+ moneySpender.PrintHowMuchEachCanSpend();
+ moneySpender.SpendMoney();
+ GoToNextStep();
+
+ TransferFilesManager transferFilesManager = new TransferFilesManager();
+
+ Console.WriteLine(transferFilesManager.GetDescriptionOfClass());
+ GoToNextStep();
+ transferFilesManager.TransferFiles();
+
+ GoToNextStep();
+ Console.WriteLine(ExecuteAllUntilConditionIsFalseFlavorDescription());
+ Console.WriteLine(ExecuteAllFlavorDescritpion());
+ GoToNextStep();
+
+ UserProcessor userProcessor = new UserProcessor();
+ userProcessor.DoStuff();
+
+ GoToNextStep();
+ Console.WriteLine(GetPitfalls());
+ }
+
+ private static void GoToNextStep()
+ {
+ Console.ReadKey();
+ Console.Clear();
+ }
+
+ public static string GetPatternDescription()
+ {
+ return @"
+Decouples sender and receiver (as a sender you don't know who will handle the request/ as a receiver you don't know who the sender is necessary)
+Hierarchical in nature
+When using the Chain of Responsibility is more effective:
+More than one object can handle a command
+The handler is not known in advance
+The handler should be determined automatically
+It’s wished that the request is addressed to a group of objects without explicitly specifying its receiver
+The group of objects that may handle the command must be specified in a dynamic way.
+Examples in real life:
+ -java.util.logging.Logger.#log()
+ -javax.servlet.Filter#doFilter()
+ -Spring Security Filter Chain";
+ }
+
+ public static string GetPitfalls()
+ {
+ return @"
+Handling/Handler guarantee - you won't be sure that someone can process the request
+Runtime configuration risk - the order matters/and it might be that the chain is not configured correctly
+Chain length/performance issues - in theory you could see a chain that is too big, and it would be a bottleneck in performance";
+ }
+
+ public static string ExeucteFirstWhenConditionMatchesFlavorDescription()
+ {
+ return @"Flavor 1: Execute first that matches the condition and exit";
+ }
+
+ public static string ExecuteAllUntilConditionIsFalseFlavorDescription()
+ {
+ return @"Flavor 2 of chain of responssibility:Execute all elements of chain until the condition does not match";
+ }
+
+ public static string ExecuteAllFlavorDescritpion()
+ {
+ return @"Flavor 3 of chain of responssibility: Execute all elements of chain";
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/TransferFileExample/FileCopyClient.cs b/src/ChainOfResponssibility/TransferFileExample/FileCopyClient.cs
new file mode 100644
index 0000000..6427ba7
--- /dev/null
+++ b/src/ChainOfResponssibility/TransferFileExample/FileCopyClient.cs
@@ -0,0 +1,18 @@
+using System;
+using System.IO;
+
+namespace ChainOfResponssibility.TransferFileExample
+{
+ public class FileCopyClient : TransferClient
+ {
+ protected override bool CanTransferTo(string destination)
+ {
+ return destination.StartsWith("file://") || Directory.Exists(Path.GetDirectoryName(destination));
+ }
+
+ protected override void Transfer(string source, string destination)
+ {
+ Console.WriteLine("File copy from: {0} to {1}", source, destination);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ChainOfResponssibility/TransferFileExample/FtpTransferClient.cs b/src/ChainOfResponssibility/TransferFileExample/FtpTransferClient.cs
new file mode 100644
index 0000000..1d84202
--- /dev/null
+++ b/src/ChainOfResponssibility/TransferFileExample/FtpTransferClient.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.TransferFileExample
+{
+ public class FtpTransferClient : TransferClient
+ {
+ protected override bool CanTransferTo(string destination)
+ {
+ return destination.StartsWith("ftp:");
+ }
+
+ protected override void Transfer(string source, string destination)
+ {
+ Console.WriteLine("FTP transfer file from: {0} to {1}", source, destination);
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/TransferFileExample/FtpsTransferClient.cs b/src/ChainOfResponssibility/TransferFileExample/FtpsTransferClient.cs
new file mode 100644
index 0000000..0cf7d91
--- /dev/null
+++ b/src/ChainOfResponssibility/TransferFileExample/FtpsTransferClient.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.TransferFileExample
+{
+ public class SftpransferClient : TransferClient
+ {
+ protected override bool CanTransferTo(string destination)
+ {
+ return destination.StartsWith("sftp:");
+ }
+
+ protected override void Transfer(string source, string destination)
+ {
+ Console.WriteLine("SFTP transfer file from: {0} to {1}", source, destination);
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/TransferFileExample/HttpTransferClient.cs b/src/ChainOfResponssibility/TransferFileExample/HttpTransferClient.cs
new file mode 100644
index 0000000..d188d23
--- /dev/null
+++ b/src/ChainOfResponssibility/TransferFileExample/HttpTransferClient.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.TransferFileExample
+{
+ public class HttpTransferClient : TransferClient
+ {
+ protected override bool CanTransferTo(string destination)
+ {
+ return destination.StartsWith("http:") || destination.StartsWith("https:");
+ }
+
+ protected override void Transfer(string source, string destination)
+ {
+ Console.WriteLine("Http transfer file from: {0} to {1}", source, destination);
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/TransferFileExample/TransferClient.cs b/src/ChainOfResponssibility/TransferFileExample/TransferClient.cs
new file mode 100644
index 0000000..196a72b
--- /dev/null
+++ b/src/ChainOfResponssibility/TransferFileExample/TransferClient.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.TransferFileExample
+{
+ public abstract class TransferClient
+ {
+ protected abstract bool CanTransferTo(string destination);
+
+ protected abstract void Transfer(string source, string destination);
+
+ protected TransferClient Successor { get; private set; }
+
+ public void TransferFile(string source, string destination)
+ {
+ if(CanTransferTo(destination))
+ {
+ Transfer(source, destination);
+ }
+ else
+ {
+ if (Successor != null)
+ Successor.TransferFile(source, destination);
+ else
+ Console.WriteLine("Could not transfer file to: {0}", destination);
+ }
+ }
+
+ public TransferClient SetSuccessor(TransferClient successor)
+ {
+ return Successor = successor;
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/TransferFileExample/TransferFilesManager.cs b/src/ChainOfResponssibility/TransferFileExample/TransferFilesManager.cs
new file mode 100644
index 0000000..eb0e606
--- /dev/null
+++ b/src/ChainOfResponssibility/TransferFileExample/TransferFilesManager.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.TransferFileExample
+{
+ public class TransferFilesManager
+ {
+ TransferClient tranferClient;
+
+ public TransferFilesManager()
+ {
+ tranferClient = new FtpTransferClient();
+ tranferClient
+ .SetSuccessor(new HttpTransferClient())
+ .SetSuccessor(new SftpransferClient())
+ .SetSuccessor(new FileCopyClient());
+ }
+
+ public void TransferFiles()
+ {
+ string src = "", dst = "";
+
+ do
+ {
+ Console.WriteLine("Source:");
+ Console.Write(">");
+ src = Console.ReadLine();
+ Console.WriteLine("Destination:");
+ Console.Write(">");
+ dst = Console.ReadLine();
+
+ if (!IsExitCode(src) && !IsExitCode(dst))
+ tranferClient.TransferFile(src, dst);
+
+ } while (!IsExitCode(src) && !IsExitCode(dst));
+ }
+
+ private static bool IsExitCode(string input)
+ {
+ return "exit".Equals(input, StringComparison.OrdinalIgnoreCase);
+ }
+
+ public string GetDescriptionOfClass()
+ {
+ return @"TransferFilesManager will try to transfer the file to the destination by trying FTP, SFTP, Http, and simple file copy";
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/ChainValidation.cs b/src/ChainOfResponssibility/Validators/ChainValidation.cs
new file mode 100644
index 0000000..fcc50be
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/ChainValidation.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators
+{
+ public abstract class ChainValidation
+ {
+ public ChainValidation Successor { get; private set; }
+
+ public ChainValidation SetSuccessor(ChainValidation successor)
+ {
+ return Successor = successor;
+ }
+
+ protected abstract ValidationResult IsValid(T obj);
+
+ public ValidationResult Validate(T obj)
+ {
+ ValidationResult result = IsValid(obj);
+
+ if (!result.IsValid)
+ return result;
+
+ if (Successor != null)
+ return Successor.Validate(obj);
+ else
+ return result;
+
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/CommandCouldNotBeParsedException.cs b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/CommandCouldNotBeParsedException.cs
new file mode 100644
index 0000000..d74b7b1
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/CommandCouldNotBeParsedException.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ internal class CommandCouldNotBeParsedException : Exception
+ {
+ public CommandCouldNotBeParsedException()
+ {
+ }
+
+ public CommandCouldNotBeParsedException(string message) : base(message)
+ {
+ }
+
+ public CommandCouldNotBeParsedException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/DuplicateRecordException.cs b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/DuplicateRecordException.cs
new file mode 100644
index 0000000..9a80b9f
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/DuplicateRecordException.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ internal class DuplicateRecordException : Exception
+ {
+ public DuplicateRecordException()
+ {
+ }
+
+ public DuplicateRecordException(string message) : base(message)
+ {
+ }
+
+ public DuplicateRecordException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/ForbiddenException.cs b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/ForbiddenException.cs
new file mode 100644
index 0000000..959e137
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/ForbiddenException.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace ChainOfResponssibility.Validators.UserEntities.Validators
+{
+ internal class ForbiddenException : Exception
+ {
+ public ForbiddenException()
+ {
+ }
+
+ public ForbiddenException(string message) : base(message)
+ {
+ }
+
+ public ForbiddenException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/NotFoundException.cs b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/NotFoundException.cs
new file mode 100644
index 0000000..8132071
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/NotFoundException.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ internal class NotFoundException : Exception
+ {
+ private int iD;
+
+ public NotFoundException()
+ {
+ }
+
+ public NotFoundException(string message) : base(message)
+ {
+ }
+
+ public NotFoundException(int iD)
+ {
+ this.iD = iD;
+ }
+
+ public NotFoundException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/ValidationResult.cs b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/ValidationResult.cs
new file mode 100644
index 0000000..ab6a0b8
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Exceptions/ValidationResult.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators
+{
+ public class ValidationResult
+ {
+ protected ValidationResult(bool isValid, Exception e)
+ {
+ IsValid = isValid;
+ Exception = e;
+ }
+
+ public static ValidationResult GetValidResult()
+ {
+ return new ValidationResult(true, null);
+ }
+
+ public static ValidationResult GetInvalidResult(Exception e)
+ {
+ return new ValidationResult(false, e);
+ }
+
+ public Exception Exception { get; set; }
+
+ public bool IsValid { get; set; }
+ }
+
+ public class ValidationResult : ValidationResult
+ {
+ public ValidationResult(bool isValid, Exception e, T model) : base(isValid, e)
+ {
+ }
+
+ public static ValidationResult GetValidResult(T model)
+ {
+ return new ValidationResult(true, null, model);
+ }
+
+ public static ValidationResult GetInvalidResult(Exception e)
+ {
+ return new ValidationResult(false, e, default(T));
+ }
+
+ public T Result { get; set; }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Infrastructure/PrincipalHelper.cs b/src/ChainOfResponssibility/Validators/UserEntities/Infrastructure/PrincipalHelper.cs
new file mode 100644
index 0000000..c50e1b8
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Infrastructure/PrincipalHelper.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities.Infrastructure
+{
+ public class PrincipalHelper
+ {
+ User authenticatedUser;
+
+ public User GetAuthenticatedUser()
+ {
+ return authenticatedUser;
+ }
+
+ public void SetAuthenticatedUser(User user)
+ {
+ authenticatedUser = user;
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Infrastructure/UserRepository.cs b/src/ChainOfResponssibility/Validators/UserEntities/Infrastructure/UserRepository.cs
new file mode 100644
index 0000000..65e9ed5
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Infrastructure/UserRepository.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ public class UserRepository
+ {
+ List users;
+ public UserRepository()
+ {
+ users = new List();
+ users.Add(new User { ID = 1, Email = "a@a.a", TenantId = 1, UserName = "a", Rights = Rights.Create | Rights.Update });
+ users.Add(new User { ID = 2, Email = "b@a.a", TenantId = 1, UserName = "b", Rights = Rights.Read});
+ users.Add(new User { ID = 2, Email = "c@a.a", TenantId = 2, UserName = "c", Rights = Rights.Create | Rights.Update | Rights.Read | Rights.Delete });
+ }
+
+ public User Get(string email)
+ {
+ return users.First(u => u.Email == email);
+ }
+
+ public bool Exists(string email)
+ {
+ return users.Any(u => u.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
+ }
+
+ public bool Exists(int id)
+ {
+ return users.Any(u => u.ID == id);
+ }
+
+ public void Add(User user)
+ {
+ lock (users)
+ {
+ int maxId = users.Max(u => u.ID);
+ user.ID = maxId + 1;
+ users.Add(user);
+ }
+
+ }
+
+ public void Update(User user)
+ {
+ User dbUser = users.First(u => u.ID == user.ID);
+
+ dbUser.Email = user.Email;
+ dbUser.TenantId = user.TenantId;
+ dbUser.UserName = user.UserName;
+ }
+
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Model/User.cs b/src/ChainOfResponssibility/Validators/UserEntities/Model/User.cs
new file mode 100644
index 0000000..dab928e
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Model/User.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ public class User
+ {
+ public int ID { get; set; }
+
+ public string UserName { get; set; }
+
+ public string Email { get; set; }
+
+ public int TenantId { get; set; }
+
+ public Rights Rights { get; set; }
+ }
+ [Flags]
+ public enum Rights
+ {
+ Create = 1 << 3,
+ Read = 1 << 2,
+ Update = 1 << 1,
+ Delete = 1 << 0
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/AuthenticateOperation.cs b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/AuthenticateOperation.cs
new file mode 100644
index 0000000..ef8b6e9
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/AuthenticateOperation.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace ChainOfResponssibility.Validators.UserEntities.UserMenu
+{
+ public class AuthenticateOperation : Operation
+ {
+ const string prefix = "authenticate as";
+ Action authenticateFunction;
+ public AuthenticateOperation(Action authenticateFunction)
+ {
+ this.authenticateFunction = authenticateFunction;
+ }
+
+ protected override bool CanExecute(string command)
+ {
+ return command.ToLower().StartsWith(prefix);
+ }
+
+ protected override void ExecuteSpecificOperation(string command)
+ {
+ string email = command.Substring(prefix.Length + 1);
+ authenticateFunction(email);
+ }
+
+ protected override string GetMessageToPrint()
+ {
+ return string.Format("To authenticate press: {0} ", prefix);
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/CreateNewUserOperation.cs b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/CreateNewUserOperation.cs
new file mode 100644
index 0000000..9a4a631
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/CreateNewUserOperation.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities.UserMenu
+{
+ public class CreateNewUserOperation : Operation
+ {
+ string prefix = "create user";
+ Action createUser;
+ public CreateNewUserOperation(Action createUser)
+ {
+ this.createUser = createUser;
+ }
+
+ protected override bool CanExecute(string command)
+ {
+ var hasCorrectPrefix = command.ToLower().StartsWith(prefix) && command.Contains(",");
+ return hasCorrectPrefix && IsInt(GetTenantId(command));
+ }
+
+ protected override void ExecuteSpecificOperation(string command)
+ {
+ string commandWithoutPrefix = command.Substring(prefix.Length);
+
+ string email = new string(commandWithoutPrefix.TakeWhile(c => c != ',').Skip(1).ToArray()).Trim();
+
+ string userName = GetUserName(commandWithoutPrefix);
+
+ int tenantId = int.Parse(GetTenantId(commandWithoutPrefix));
+ createUser(email, userName, tenantId);
+ }
+
+ public static string GetUserName(string command)
+ {
+ string commandWithoutEmail = command.Substring(command.IndexOf(',') + 1);
+ string userName = commandWithoutEmail.Substring(0, commandWithoutEmail.LastIndexOf(','));
+ return userName.Trim();
+ }
+
+ private static string GetTenantId(string command)
+ {
+ return command.Substring(command.LastIndexOf(',') + 1).Trim();
+ }
+
+ protected override string GetMessageToPrint()
+ {
+ return string.Format("To create a new user press: create user , , ");
+ }
+
+ private bool IsInt(string tenantId)
+ {
+ int number;
+ return int.TryParse(tenantId, out number);
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/Operation.cs b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/Operation.cs
new file mode 100644
index 0000000..44006d1
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/Operation.cs
@@ -0,0 +1,49 @@
+using System;
+
+namespace ChainOfResponssibility.Validators.UserEntities.UserMenu
+{
+ public abstract class Operation
+ {
+ protected abstract bool CanExecute(string command);
+
+ protected abstract void ExecuteSpecificOperation(string command);
+
+ protected abstract string GetMessageToPrint();
+
+ public Operation Successor { get; private set; }
+
+ public Operation SetSuccessor(Operation successor)
+ {
+ return Successor = successor;
+ }
+
+ public ValidationResult Execute(string command)
+ {
+ if (CanExecute(command))
+ {
+ ExecuteSpecificOperation(command);
+ return ValidationResult.GetValidResult();
+ }
+ else
+ {
+ if (Successor != null)
+ return Successor.Execute(command);
+ else
+ return GetInvalidResult(command);
+ }
+ }
+
+ public void PrintMenu()
+ {
+ Console.WriteLine(GetMessageToPrint());
+
+ if (Successor != null)
+ Successor.PrintMenu();
+ }
+
+ private static ValidationResult GetInvalidResult(string command)
+ {
+ return ValidationResult.GetInvalidResult(new CommandCouldNotBeParsedException(command));
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/UpdateUserOperation.cs b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/UpdateUserOperation.cs
new file mode 100644
index 0000000..8ca3927
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/UserMenu/UpdateUserOperation.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities.UserMenu
+{
+ public class UpdateUserOperation
+ {
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/UserProcessor.cs b/src/ChainOfResponssibility/Validators/UserEntities/UserProcessor.cs
new file mode 100644
index 0000000..75fbd43
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/UserProcessor.cs
@@ -0,0 +1,76 @@
+using ChainOfResponssibility.Validators.UserEntities.Infrastructure;
+using ChainOfResponssibility.Validators.UserEntities.UserMenu;
+using ChainOfResponssibility.Validators.UserEntities.Validators;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ public class UserProcessor
+ {
+ UserRepository userRepository;
+ PrincipalHelper principalHelper;
+ Operation operation;
+ ChainValidation userCreationValidation;
+ ChainValidation authenticateUserValidation;
+ public UserProcessor()
+ {
+ userRepository = new UserRepository();
+ principalHelper = new PrincipalHelper();
+ operation = new AuthenticateOperation(AuthenticateUser);
+ operation.SetSuccessor(new CreateNewUserOperation(CreateNewUser));
+
+ userCreationValidation = new IsAuthorisedToDoOperationsOnUser(principalHelper, Rights.Create);
+ userCreationValidation.SetSuccessor(new ValidateNoDuplicateEmail(userRepository));
+
+ authenticateUserValidation = new ValidateUserExistsInDb(userRepository);
+
+ }
+
+ private void CreateNewUser(string email, string userName, int tenantId)
+ {
+ User user = new User { Email = email, UserName = userName, TenantId = tenantId };
+ var result = userCreationValidation.Validate(user);
+
+ if (result.IsValid)
+ userRepository.Add(user);
+ else
+ Console.WriteLine(result.Exception);
+ }
+
+ private void AuthenticateUser(string email)
+ {
+ var result = authenticateUserValidation.Validate(new User { Email = email });
+
+ if (result.IsValid)
+ {
+ principalHelper.SetAuthenticatedUser(userRepository.Get(email));
+ Console.WriteLine("Authentication successful");
+ }
+ else
+ Console.WriteLine(result.Exception.Message);
+ }
+
+ public void DoStuff()
+ {
+ string userInput;
+ do
+ {
+ operation.PrintMenu();
+ Console.Write(">");
+ userInput = Console.ReadLine();
+
+ if (!IsExitCode(userInput))
+ operation.Execute(userInput);
+
+ } while (!IsExitCode(userInput));
+ }
+
+ private static bool IsExitCode(string input)
+ {
+ return "exit".Equals(input, StringComparison.OrdinalIgnoreCase);
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Validators/IsAuthorisedToDoOperationsOnUser.cs b/src/ChainOfResponssibility/Validators/UserEntities/Validators/IsAuthorisedToDoOperationsOnUser.cs
new file mode 100644
index 0000000..b14d4c7
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Validators/IsAuthorisedToDoOperationsOnUser.cs
@@ -0,0 +1,35 @@
+using ChainOfResponssibility.Validators.UserEntities.Infrastructure;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities.Validators
+{
+ public class IsAuthorisedToDoOperationsOnUser : ChainValidation
+ {
+ PrincipalHelper principalHelper;
+ Rights rights;
+ public IsAuthorisedToDoOperationsOnUser(PrincipalHelper principalHelper, Rights rights)
+ {
+ this.principalHelper = principalHelper;
+ this.rights = rights;
+ }
+
+ protected override ValidationResult IsValid(User obj)
+ {
+ User authenticatedUser = principalHelper.GetAuthenticatedUser();
+
+ if (authenticatedUser == null)
+ return ValidationResult.GetInvalidResult(new ForbiddenException("Only authenticated users may create new users"));
+
+ if (!authenticatedUser.Rights.HasFlag(rights))
+ return ValidationResult.GetInvalidResult(new ForbiddenException(string.Format("Unauthorised to do {0} on user", rights)));
+
+ if (authenticatedUser.TenantId != obj.TenantId)
+ return ValidationResult.GetInvalidResult(new ForbiddenException("Cannot create user for another tenant"));
+
+ return ValidationResult.GetValidResult();
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Validators/ValidateNoDuplicateEmail.cs b/src/ChainOfResponssibility/Validators/UserEntities/Validators/ValidateNoDuplicateEmail.cs
new file mode 100644
index 0000000..24927d0
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Validators/ValidateNoDuplicateEmail.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ public class ValidateNoDuplicateEmail : ChainValidation
+ {
+ UserRepository userRepository;
+ public ValidateNoDuplicateEmail(UserRepository userRepository)
+ {
+ this.userRepository = userRepository;
+
+ }
+ protected override ValidationResult IsValid(User obj)
+ {
+ if (userRepository.Exists(obj.Email))
+ return ValidationResult.GetInvalidResult(new DuplicateRecordException(obj.Email));
+ else
+ return ValidationResult.GetValidResult();
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/Validators/UserEntities/Validators/ValidateUserExistsInDb.cs b/src/ChainOfResponssibility/Validators/UserEntities/Validators/ValidateUserExistsInDb.cs
new file mode 100644
index 0000000..743ae66
--- /dev/null
+++ b/src/ChainOfResponssibility/Validators/UserEntities/Validators/ValidateUserExistsInDb.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ChainOfResponssibility.Validators.UserEntities
+{
+ public class ValidateUserExistsInDb : ChainValidation
+ {
+ UserRepository userRepository;
+ public ValidateUserExistsInDb(UserRepository userRepository)
+ {
+ this.userRepository = userRepository;
+ }
+
+ protected override ValidationResult IsValid(User obj)
+ {
+ bool userExists = userRepository.Exists(obj.Email);
+
+ if (userExists)
+ return ValidationResult.GetValidResult();
+ else
+ return ValidationResult.GetInvalidResult(new NotFoundException(obj.ID));
+
+ }
+ }
+}
diff --git a/src/ChainOfResponssibility/project.json b/src/ChainOfResponssibility/project.json
new file mode 100644
index 0000000..ed8608d
--- /dev/null
+++ b/src/ChainOfResponssibility/project.json
@@ -0,0 +1,13 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+ "NETStandard.Library": "1.5.0-rc2-24027"
+ },
+
+ "frameworks": {
+ "netstandard1.5": {
+ "imports": "dnxcore50"
+ }
+ }
+}
diff --git a/src/CommandPattern/Class1.cs b/src/CommandPattern/Class1.cs
new file mode 100644
index 0000000..1ece8d3
--- /dev/null
+++ b/src/CommandPattern/Class1.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace CommandPattern
+{
+ // This project can output the Class library as a NuGet Package.
+ // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
+ public class Class1
+ {
+ public Class1()
+ {
+ }
+ }
+}
diff --git a/src/CommandPattern/CommandPattern.xproj b/src/CommandPattern/CommandPattern.xproj
new file mode 100644
index 0000000..cf279a6
--- /dev/null
+++ b/src/CommandPattern/CommandPattern.xproj
@@ -0,0 +1,21 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ ccc23c3a-7a67-40bd-80fb-c4d2c0342e50
+ CommandPattern
+ .\obj
+ .\bin\
+ v4.6.1
+
+
+
+ 2.0
+
+
+
diff --git a/src/CommandPattern/Properties/AssemblyInfo.cs b/src/CommandPattern/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9dd60d9
--- /dev/null
+++ b/src/CommandPattern/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+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: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Hewlett-Packard Company")]
+[assembly: AssemblyProduct("CommandPattern")]
+[assembly: AssemblyTrademark("")]
+
+// 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("ccc23c3a-7a67-40bd-80fb-c4d2c0342e50")]
diff --git a/src/CommandPattern/project.json b/src/CommandPattern/project.json
new file mode 100644
index 0000000..ed8608d
--- /dev/null
+++ b/src/CommandPattern/project.json
@@ -0,0 +1,13 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+ "NETStandard.Library": "1.5.0-rc2-24027"
+ },
+
+ "frameworks": {
+ "netstandard1.5": {
+ "imports": "dnxcore50"
+ }
+ }
+}