diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 1cf6d4c..744f3c6 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -63,6 +63,7 @@ jobs:
dotnet pack ./Email/Core/Odin.Email.csproj --configuration $CONFIGURATION --output $PACKAGE_DIR
dotnet pack ./Logging/Core/Odin.Logging.csproj --configuration $CONFIGURATION --output $PACKAGE_DIR
dotnet pack ./Messaging/RabbitMq/Odin.Messaging.RabbitMq.csproj --configuration $CONFIGURATION --output $PACKAGE_DIR
+ dotnet pack ./Patterns/CommandHandler/Odin.Patterns.CommandHandler.csproj --configuration $CONFIGURATION --output $PACKAGE_DIR
dotnet pack ./RemoteFiles/Abstractions/Odin.RemoteFiles.Abstractions.csproj --configuration $CONFIGURATION --output $PACKAGE_DIR
dotnet pack ./RemoteFiles/SFTP/Odin.RemoteFiles.SFTP.csproj --configuration $CONFIGURATION --output $PACKAGE_DIR
dotnet pack ./RemoteFiles/Core/Odin.RemoteFiles.csproj --configuration $CONFIGURATION --output $PACKAGE_DIR
diff --git a/Odin.sln b/Odin.sln
index 108f5ae..bcfc096 100644
--- a/Odin.sln
+++ b/Odin.sln
@@ -45,6 +45,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{4F52FD
README.md = README.md
GitVersion.yml = GitVersion.yml
.gitignore = .gitignore
+ TestsOnly.sln = TestsOnly.sln
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "System", "System", "{73BA62BB-2B41-2DC4-C714-51B3D4C2A215}"
@@ -98,6 +99,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Odin.System", "System
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Odin.DesignContracts.Analyzers", "DesignContracts\Analyzers\Odin.DesignContracts.Analyzers.csproj", "{12C40512-CA83-4209-9318-6CBCABF8C798}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Odin.Patterns.CommandHandler", "Patterns\CommandHandler\Odin.Patterns.CommandHandler.csproj", "{382C1CC0-F981-4682-9EFD-4471955327C3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Patterns", "Patterns", "{605A7674-8EA4-458D-9FEB-A86C927AC0F0}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -224,6 +229,10 @@ Global
{12C40512-CA83-4209-9318-6CBCABF8C798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12C40512-CA83-4209-9318-6CBCABF8C798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12C40512-CA83-4209-9318-6CBCABF8C798}.Release|Any CPU.Build.0 = Release|Any CPU
+ {382C1CC0-F981-4682-9EFD-4471955327C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {382C1CC0-F981-4682-9EFD-4471955327C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {382C1CC0-F981-4682-9EFD-4471955327C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {382C1CC0-F981-4682-9EFD-4471955327C3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CE323D9C-635B-EFD3-5B3F-7CE371D8A86A} = {BF440C74-E223-3CBF-8FA7-83F7D164F7C3}
@@ -256,5 +265,6 @@ Global
{957966BC-FE0E-4206-BDD8-F04591AB836E} = {73BA62BB-2B41-2DC4-C714-51B3D4C2A215}
{12C40512-CA83-4209-9318-6CBCABF8C798} = {9E3E1A13-9A74-4895-98A9-D96F4E0ED4B7}
{E450FC74-0DBE-320A-FE7A-87255CB4DFAB} = {73BA62BB-2B41-2DC4-C714-51B3D4C2A215}
+ {382C1CC0-F981-4682-9EFD-4471955327C3} = {605A7674-8EA4-458D-9FEB-A86C927AC0F0}
EndGlobalSection
EndGlobal
diff --git a/Patterns/CommandHandler/Contracts.cs b/Patterns/CommandHandler/Contracts.cs
new file mode 100644
index 0000000..313ae95
--- /dev/null
+++ b/Patterns/CommandHandler/Contracts.cs
@@ -0,0 +1,35 @@
+namespace Odin.Patterns.CommandHandler;
+
+///
+/// Defines a command request that doesn't return a value
+///
+public interface ICommand { }
+
+///
+/// Defines a command request that returns an operation result
+/// (e.g., a new ID, a Result class, etc.)
+/// or could be a query that returns query results data.
+///
+///
+public interface ICommand { }
+
+///
+/// Defines the handling implementation for a command request that does not return a Result.
+///
+///
+public interface ICommandHandler
+ where TCommand : ICommand
+{
+ Task HandleAsync(TCommand command, CancellationToken ct = default);
+}
+
+///
+/// Defines the handling implementation for a command request that returns a Result.
+///
+///
+///
+public interface ICommandHandler
+ where TCommand : ICommand
+{
+ Task HandleAsync(TCommand command, CancellationToken ct = default);
+}
\ No newline at end of file
diff --git a/Patterns/CommandHandler/Odin.Patterns.CommandHandler.csproj b/Patterns/CommandHandler/Odin.Patterns.CommandHandler.csproj
new file mode 100644
index 0000000..e7db217
--- /dev/null
+++ b/Patterns/CommandHandler/Odin.Patterns.CommandHandler.csproj
@@ -0,0 +1,19 @@
+
+
+ net8.0;net9.0;net10.0
+ Odin.Patterns
+ true
+ enable
+ icon.png
+ README.md
+
+
+
+ 1591;1573;
+
+
+
+
+
+
+
diff --git a/Patterns/README.md b/Patterns/README.md
new file mode 100644
index 0000000..6e9a86d
--- /dev/null
+++ b/Patterns/README.md
@@ -0,0 +1,2 @@
+## About Odin.Patterns
+~~~~
\ No newline at end of file