Add project files.

This commit is contained in:
David Lebee 2021-02-01 23:31:07 -05:00
parent 4d8f170812
commit c61ebca4b6
16 changed files with 353 additions and 0 deletions

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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<CommandNameAttribute>();
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; }
}
}

View File

@ -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; }
}
}

View File

@ -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<IQueryMeta> 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<ICommandMeta> GetCommands();
}
}

View File

@ -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; }
}
}

View File

@ -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<QueryNameAttribute>();
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; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace PoweredSoft.CQRS.Abstractions
{
public interface ICommandHandler<TCommand>
where TCommand : class
{
Task HandleAsync(TCommand command, CancellationToken cancellationToken = default);
}
public interface ICommandHandler<TCommand, TCommandResult>
where TCommand : class
{
Task<TCommandResult> HandleAsync(TCommand command, CancellationToken cancellationToken = default);
}
}

View File

@ -0,0 +1,11 @@
using System.Threading;
using System.Threading.Tasks;
namespace PoweredSoft.CQRS.Abstractions
{
public interface IQueryHandler<TQuery, TQueryResult>
where TQuery : class
{
Task<TQueryResult> HandleAsync(TQuery query, CancellationToken cancellationToken = default);
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />
</ItemGroup>
</Project>

View File

@ -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<TQuery, TQueryResult, TQueryHandler>(this IServiceCollection services)
where TQuery : class
where TQueryHandler : class, IQueryHandler<TQuery, TQueryResult>
{
// add handler to DI.
services.AddTransient<IQueryHandler<TQuery, TQueryResult>, TQueryHandler>();
// add for discovery purposes.
var queryMeta = new QueryMeta(typeof(TQuery), typeof(IQueryHandler<TQuery, TQueryResult>), typeof(TQueryResult));
services.AddSingleton<IQueryMeta>(queryMeta);
return services;
}
public static IServiceCollection AddCommand<TCommand, TCommandResult, TCommandHandler>(this IServiceCollection services)
where TCommand : class
where TCommandHandler : class, ICommandHandler<TCommand, TCommandResult>
{
// add handler to DI.
services.AddTransient<ICommandHandler<TCommand, TCommandResult>, TCommandHandler>();
// add for discovery purposes.
var commandMeta = new CommandMeta(typeof(TCommand), typeof(ICommandHandler<TCommand>), typeof(TCommandResult));
services.AddSingleton<ICommandMeta>(commandMeta);
return services;
}
public static IServiceCollection AddCommand<TCommand, TCommandHandler>(this IServiceCollection services)
where TCommand : class
where TCommandHandler : class, ICommandHandler<TCommand>
{
// add handler to DI.
services.AddTransient<ICommandHandler<TCommand>, TCommandHandler>();
// add for discovery purposes.
var commandMeta = new CommandMeta(typeof(TCommand), typeof(ICommandHandler<TCommand>));
services.AddSingleton<ICommandMeta>(commandMeta);
return services;
}
}
}

31
PoweredSoft.CQRS.sln Normal file
View File

@ -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

View File

@ -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<ICommandMeta> commandMetas;
public CommandDiscovery(IEnumerable<ICommandMeta> commandMetas)
{
this.commandMetas = commandMetas;
}
public virtual IEnumerable<ICommandMeta> 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);
}
}

View File

@ -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<IQueryMeta> queryMetas;
public QueryDiscovery(IEnumerable<IQueryMeta> queryMetas)
{
this.queryMetas = queryMetas;
}
public virtual IEnumerable<IQueryMeta> 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);
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PoweredSoft.CQRS.Abstractions\PoweredSoft.CQRS.Abstractions.csproj" />
</ItemGroup>
</Project>

View File

@ -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<IQueryDiscovery, QueryDiscovery>();
services.TryAddTransient<ICommandDiscovery, CommandDiscovery>();
return services;
}
}
}