From c61ebca4b6a68d06d586fe68a672aaaafd9d43b5 Mon Sep 17 00:00:00 2001 From: David Lebee Date: Mon, 1 Feb 2021 23:31:07 -0500 Subject: [PATCH] Add project files. --- .../Attributes/CommandNameAttribute.cs | 17 ++++++ .../Attributes/QueryNameAttribute.cs | 15 ++++++ .../Discovery/CommandMeta.cs | 37 +++++++++++++ .../Discovery/ICommandMeta.cs | 12 +++++ .../Discovery/IQueryDiscovery.cs | 24 +++++++++ .../Discovery/IQueryMeta.cs | 15 ++++++ .../Discovery/QueryMeta.cs | 31 +++++++++++ .../ICommandHandler.cs | 18 +++++++ .../IQueryHandler.cs | 11 ++++ .../PoweredSoft.CQRS.Abstractions.csproj | 9 ++++ .../ServiceCollectionExtensions.cs | 53 +++++++++++++++++++ PoweredSoft.CQRS.sln | 31 +++++++++++ .../Discovery/CommandDiscovery.cs | 23 ++++++++ PoweredSoft.CQRS/Discovery/QueryDiscovery.cs | 24 +++++++++ PoweredSoft.CQRS/PoweredSoft.CQRS.csproj | 13 +++++ .../ServiceCollectionExtensions.cs | 20 +++++++ 16 files changed, 353 insertions(+) create mode 100644 PoweredSoft.CQRS.Abstractions/Attributes/CommandNameAttribute.cs create mode 100644 PoweredSoft.CQRS.Abstractions/Attributes/QueryNameAttribute.cs create mode 100644 PoweredSoft.CQRS.Abstractions/Discovery/CommandMeta.cs create mode 100644 PoweredSoft.CQRS.Abstractions/Discovery/ICommandMeta.cs create mode 100644 PoweredSoft.CQRS.Abstractions/Discovery/IQueryDiscovery.cs create mode 100644 PoweredSoft.CQRS.Abstractions/Discovery/IQueryMeta.cs create mode 100644 PoweredSoft.CQRS.Abstractions/Discovery/QueryMeta.cs create mode 100644 PoweredSoft.CQRS.Abstractions/ICommandHandler.cs create mode 100644 PoweredSoft.CQRS.Abstractions/IQueryHandler.cs create mode 100644 PoweredSoft.CQRS.Abstractions/PoweredSoft.CQRS.Abstractions.csproj create mode 100644 PoweredSoft.CQRS.Abstractions/ServiceCollectionExtensions.cs create mode 100644 PoweredSoft.CQRS.sln create mode 100644 PoweredSoft.CQRS/Discovery/CommandDiscovery.cs create mode 100644 PoweredSoft.CQRS/Discovery/QueryDiscovery.cs create mode 100644 PoweredSoft.CQRS/PoweredSoft.CQRS.csproj create mode 100644 PoweredSoft.CQRS/ServiceCollectionExtensions.cs diff --git a/PoweredSoft.CQRS.Abstractions/Attributes/CommandNameAttribute.cs b/PoweredSoft.CQRS.Abstractions/Attributes/CommandNameAttribute.cs new file mode 100644 index 0000000..5e4204d --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/Attributes/CommandNameAttribute.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.CQRS.Abstractions.Attributes +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false)] + public class CommandNameAttribute : Attribute + { + public CommandNameAttribute(string name) + { + Name = name; + } + + public string Name { get; } + } +} diff --git a/PoweredSoft.CQRS.Abstractions/Attributes/QueryNameAttribute.cs b/PoweredSoft.CQRS.Abstractions/Attributes/QueryNameAttribute.cs new file mode 100644 index 0000000..329b996 --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/Attributes/QueryNameAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace PoweredSoft.CQRS.Abstractions.Attributes +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false)] + public class QueryNameAttribute : Attribute + { + public QueryNameAttribute(string name) + { + Name = name; + } + + public string Name { get; } + } +} diff --git a/PoweredSoft.CQRS.Abstractions/Discovery/CommandMeta.cs b/PoweredSoft.CQRS.Abstractions/Discovery/CommandMeta.cs new file mode 100644 index 0000000..f875d43 --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/Discovery/CommandMeta.cs @@ -0,0 +1,37 @@ +using PoweredSoft.CQRS.Abstractions.Attributes; +using System; +using System.Reflection; + +namespace PoweredSoft.CQRS.Abstractions.Discovery +{ + public class CommandMeta : ICommandMeta + { + public CommandMeta(Type commandType, Type serviceType, Type commandResultType) + { + CommandType = commandType; + ServiceType = serviceType; + CommandResultType = commandResultType; + } + + public CommandMeta(Type commandType, Type serviceType) + { + CommandType = commandType; + ServiceType = serviceType; + } + + protected virtual CommandNameAttribute NameAttribute => CommandType.GetCustomAttribute(); + + public virtual string Name + { + get + { + var name = NameAttribute?.Name ?? CommandType.Name.Replace("Command", string.Empty); + return name; + } + } + + public virtual Type CommandType { get; } + public virtual Type ServiceType { get; } + public virtual Type CommandResultType { get; } + } +} diff --git a/PoweredSoft.CQRS.Abstractions/Discovery/ICommandMeta.cs b/PoweredSoft.CQRS.Abstractions/Discovery/ICommandMeta.cs new file mode 100644 index 0000000..96720fc --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/Discovery/ICommandMeta.cs @@ -0,0 +1,12 @@ +using System; + +namespace PoweredSoft.CQRS.Abstractions.Discovery +{ + public interface ICommandMeta + { + string Name { get; } + Type CommandType { get; } + Type ServiceType { get; } + Type CommandResultType { get; } + } +} diff --git a/PoweredSoft.CQRS.Abstractions/Discovery/IQueryDiscovery.cs b/PoweredSoft.CQRS.Abstractions/Discovery/IQueryDiscovery.cs new file mode 100644 index 0000000..f9c1915 --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/Discovery/IQueryDiscovery.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.CQRS.Abstractions.Discovery +{ + public interface IQueryDiscovery + { + IQueryMeta FindQuery(string name); + IQueryMeta FindQuery(Type queryType); + IEnumerable GetQueries(); + bool QueryExists(string name); + bool QueryExists(Type queryType); + } + + public interface ICommandDiscovery + { + bool CommandExists(string name); + bool CommandExists(Type commandType); + ICommandMeta FindCommand(string name); + ICommandMeta FindCommand(Type commandType); + IEnumerable GetCommands(); + } +} diff --git a/PoweredSoft.CQRS.Abstractions/Discovery/IQueryMeta.cs b/PoweredSoft.CQRS.Abstractions/Discovery/IQueryMeta.cs new file mode 100644 index 0000000..8bd01a3 --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/Discovery/IQueryMeta.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace PoweredSoft.CQRS.Abstractions.Discovery +{ + public interface IQueryMeta + { + string Name { get; } + Type QueryType { get; } + Type ServiceType { get; } + Type QueryResultType { get; } + } +} diff --git a/PoweredSoft.CQRS.Abstractions/Discovery/QueryMeta.cs b/PoweredSoft.CQRS.Abstractions/Discovery/QueryMeta.cs new file mode 100644 index 0000000..c3a347f --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/Discovery/QueryMeta.cs @@ -0,0 +1,31 @@ +using PoweredSoft.CQRS.Abstractions.Attributes; +using System; +using System.Reflection; + +namespace PoweredSoft.CQRS.Abstractions.Discovery +{ + public class QueryMeta : IQueryMeta + { + public QueryMeta(Type queryType, Type serviceType, Type queryResultType) + { + QueryType = queryType; + ServiceType = serviceType; + QueryResultType = queryResultType; + } + + protected virtual QueryNameAttribute NameAttribute => QueryType.GetCustomAttribute(); + + public virtual string Name + { + get + { + var name = NameAttribute?.Name ?? QueryType.Name.Replace("Query", string.Empty); + return name; + } + } + + public virtual Type QueryType { get; } + public virtual Type ServiceType { get; } + public virtual Type QueryResultType { get; } + } +} diff --git a/PoweredSoft.CQRS.Abstractions/ICommandHandler.cs b/PoweredSoft.CQRS.Abstractions/ICommandHandler.cs new file mode 100644 index 0000000..3afc5f4 --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/ICommandHandler.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace PoweredSoft.CQRS.Abstractions +{ + public interface ICommandHandler + where TCommand : class + { + Task HandleAsync(TCommand command, CancellationToken cancellationToken = default); + } + + public interface ICommandHandler + where TCommand : class + { + Task HandleAsync(TCommand command, CancellationToken cancellationToken = default); + } +} diff --git a/PoweredSoft.CQRS.Abstractions/IQueryHandler.cs b/PoweredSoft.CQRS.Abstractions/IQueryHandler.cs new file mode 100644 index 0000000..9061efc --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/IQueryHandler.cs @@ -0,0 +1,11 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace PoweredSoft.CQRS.Abstractions +{ + public interface IQueryHandler + where TQuery : class + { + Task HandleAsync(TQuery query, CancellationToken cancellationToken = default); + } +} diff --git a/PoweredSoft.CQRS.Abstractions/PoweredSoft.CQRS.Abstractions.csproj b/PoweredSoft.CQRS.Abstractions/PoweredSoft.CQRS.Abstractions.csproj new file mode 100644 index 0000000..5e31d58 --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/PoweredSoft.CQRS.Abstractions.csproj @@ -0,0 +1,9 @@ + + + + netstandard2.0 + + + + + diff --git a/PoweredSoft.CQRS.Abstractions/ServiceCollectionExtensions.cs b/PoweredSoft.CQRS.Abstractions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..d54e06a --- /dev/null +++ b/PoweredSoft.CQRS.Abstractions/ServiceCollectionExtensions.cs @@ -0,0 +1,53 @@ +using Microsoft.Extensions.DependencyInjection; +using PoweredSoft.CQRS.Abstractions.Discovery; +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.CQRS.Abstractions +{ + public static class ServiceCollectionExtensions + { + public static IServiceCollection AddQuery(this IServiceCollection services) + where TQuery : class + where TQueryHandler : class, IQueryHandler + { + // add handler to DI. + services.AddTransient, TQueryHandler>(); + + // add for discovery purposes. + var queryMeta = new QueryMeta(typeof(TQuery), typeof(IQueryHandler), typeof(TQueryResult)); + services.AddSingleton(queryMeta); + + return services; + } + + public static IServiceCollection AddCommand(this IServiceCollection services) + where TCommand : class + where TCommandHandler : class, ICommandHandler + { + // add handler to DI. + services.AddTransient, TCommandHandler>(); + + // add for discovery purposes. + var commandMeta = new CommandMeta(typeof(TCommand), typeof(ICommandHandler), typeof(TCommandResult)); + services.AddSingleton(commandMeta); + + return services; + } + + public static IServiceCollection AddCommand(this IServiceCollection services) + where TCommand : class + where TCommandHandler : class, ICommandHandler + { + // add handler to DI. + services.AddTransient, TCommandHandler>(); + + // add for discovery purposes. + var commandMeta = new CommandMeta(typeof(TCommand), typeof(ICommandHandler)); + services.AddSingleton(commandMeta); + + return services; + } + } +} diff --git a/PoweredSoft.CQRS.sln b/PoweredSoft.CQRS.sln new file mode 100644 index 0000000..f1d1358 --- /dev/null +++ b/PoweredSoft.CQRS.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30907.101 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.CQRS.Abstractions", "PoweredSoft.CQRS.Abstractions\PoweredSoft.CQRS.Abstractions.csproj", "{ED78E19D-31D4-4783-AE9E-2844A8541277}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.CQRS", "PoweredSoft.CQRS\PoweredSoft.CQRS.csproj", "{7069B98F-8736-4114-8AF5-1ACE094E6238}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ED78E19D-31D4-4783-AE9E-2844A8541277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED78E19D-31D4-4783-AE9E-2844A8541277}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED78E19D-31D4-4783-AE9E-2844A8541277}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED78E19D-31D4-4783-AE9E-2844A8541277}.Release|Any CPU.Build.0 = Release|Any CPU + {7069B98F-8736-4114-8AF5-1ACE094E6238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7069B98F-8736-4114-8AF5-1ACE094E6238}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7069B98F-8736-4114-8AF5-1ACE094E6238}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7069B98F-8736-4114-8AF5-1ACE094E6238}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D6D431EA-C04F-462B-8033-60F510FEB49E} + EndGlobalSection +EndGlobal diff --git a/PoweredSoft.CQRS/Discovery/CommandDiscovery.cs b/PoweredSoft.CQRS/Discovery/CommandDiscovery.cs new file mode 100644 index 0000000..53f6d33 --- /dev/null +++ b/PoweredSoft.CQRS/Discovery/CommandDiscovery.cs @@ -0,0 +1,23 @@ +using PoweredSoft.CQRS.Abstractions.Discovery; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PoweredSoft.CQRS.Discovery +{ + public class CommandDiscovery : ICommandDiscovery + { + private readonly IEnumerable commandMetas; + + public CommandDiscovery(IEnumerable commandMetas) + { + this.commandMetas = commandMetas; + } + + public virtual IEnumerable GetCommands() => commandMetas; + public virtual ICommandMeta FindCommand(string name) => commandMetas.FirstOrDefault(t => t.Name == name); + public virtual ICommandMeta FindCommand(Type commandType) => commandMetas.FirstOrDefault(t => t.CommandType == commandType); + public virtual bool CommandExists(string name) => commandMetas.Any(t => t.Name == name); + public virtual bool CommandExists(Type commandType) => commandMetas.Any(t => t.CommandType == commandType); + } +} diff --git a/PoweredSoft.CQRS/Discovery/QueryDiscovery.cs b/PoweredSoft.CQRS/Discovery/QueryDiscovery.cs new file mode 100644 index 0000000..4f4a1f8 --- /dev/null +++ b/PoweredSoft.CQRS/Discovery/QueryDiscovery.cs @@ -0,0 +1,24 @@ +using PoweredSoft.CQRS.Abstractions.Discovery; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace PoweredSoft.CQRS.Discovery +{ + public class QueryDiscovery : IQueryDiscovery + { + private readonly IEnumerable queryMetas; + + public QueryDiscovery(IEnumerable queryMetas) + { + this.queryMetas = queryMetas; + } + + public virtual IEnumerable GetQueries() => queryMetas; + public virtual IQueryMeta FindQuery(string name) => queryMetas.FirstOrDefault(t => t.Name == name); + public virtual IQueryMeta FindQuery(Type queryType) => queryMetas.FirstOrDefault(t => t.QueryType == queryType); + public virtual bool QueryExists(string name) => queryMetas.Any(t => t.Name == name); + public virtual bool QueryExists(Type queryType) => queryMetas.Any(t => t.QueryType == queryType); + } +} diff --git a/PoweredSoft.CQRS/PoweredSoft.CQRS.csproj b/PoweredSoft.CQRS/PoweredSoft.CQRS.csproj new file mode 100644 index 0000000..874be33 --- /dev/null +++ b/PoweredSoft.CQRS/PoweredSoft.CQRS.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + + + + + + + + + diff --git a/PoweredSoft.CQRS/ServiceCollectionExtensions.cs b/PoweredSoft.CQRS/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..b1dbb0a --- /dev/null +++ b/PoweredSoft.CQRS/ServiceCollectionExtensions.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using PoweredSoft.CQRS.Abstractions.Discovery; +using PoweredSoft.CQRS.Discovery; +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.CQRS +{ + public static class ServiceCollectionExtensions + { + public static IServiceCollection AddPoweredSoftCQRS(this IServiceCollection services) + { + services.TryAddTransient(); + services.TryAddTransient(); + return services; + } + } +}