1.1, 1.2
This commit is contained in:
parent
dea62c2434
commit
87273f6fcf
@ -42,7 +42,8 @@
|
||||
"WebFetch(domain:blog.rsuter.com)",
|
||||
"WebFetch(domain:natemcmaster.com)",
|
||||
"WebFetch(domain:www.nuget.org)",
|
||||
"Bash(mkdir:*)"
|
||||
"Bash(mkdir:*)",
|
||||
"Bash(nul)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,6 +3,9 @@
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
nul
|
||||
Svrnty.Sample/nul
|
||||
|
||||
.research/
|
||||
|
||||
# User-specific files
|
||||
|
||||
@ -6,46 +6,45 @@ namespace Svrnty.CQRS.Abstractions.Discovery;
|
||||
|
||||
public sealed class CommandMeta : ICommandMeta
|
||||
{
|
||||
private readonly string _name;
|
||||
private readonly string _lowerCamelCaseName;
|
||||
|
||||
public CommandMeta(Type commandType, Type serviceType, Type commandResultType)
|
||||
{
|
||||
CommandType = commandType;
|
||||
ServiceType = serviceType;
|
||||
CommandResultType = commandResultType;
|
||||
|
||||
// Cache reflection and computed values once in constructor
|
||||
var nameAttribute = commandType.GetCustomAttribute<CommandNameAttribute>();
|
||||
_name = nameAttribute?.Name ?? commandType.Name.Replace("Command", string.Empty);
|
||||
_lowerCamelCaseName = ComputeLowerCamelCaseName(_name);
|
||||
}
|
||||
|
||||
public CommandMeta(Type commandType, Type serviceType)
|
||||
{
|
||||
CommandType = commandType;
|
||||
ServiceType = serviceType;
|
||||
|
||||
// Cache reflection and computed values once in constructor
|
||||
var nameAttribute = commandType.GetCustomAttribute<CommandNameAttribute>();
|
||||
_name = nameAttribute?.Name ?? commandType.Name.Replace("Command", string.Empty);
|
||||
_lowerCamelCaseName = ComputeLowerCamelCaseName(_name);
|
||||
}
|
||||
|
||||
private CommandNameAttribute NameAttribute => CommandType.GetCustomAttribute<CommandNameAttribute>();
|
||||
|
||||
public string Name
|
||||
private static string ComputeLowerCamelCaseName(string name)
|
||||
{
|
||||
get
|
||||
{
|
||||
var name = NameAttribute?.Name ?? CommandType.Name.Replace("Command", string.Empty);
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return name;
|
||||
}
|
||||
|
||||
var firstLetter = char.ToLowerInvariant(name[0]);
|
||||
return $"{firstLetter}{name.Substring(1)}";
|
||||
}
|
||||
|
||||
public string Name => _name;
|
||||
public Type CommandType { get; }
|
||||
public Type ServiceType { get; }
|
||||
public Type CommandResultType { get; }
|
||||
|
||||
public string LowerCamelCaseName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(Name))
|
||||
return Name;
|
||||
|
||||
var name = Name;
|
||||
var firstLetter = Char.ToLowerInvariant(name[0]);
|
||||
var ret = $"{firstLetter}{name.Substring(1)}";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
public string LowerCamelCaseName => _lowerCamelCaseName;
|
||||
}
|
||||
|
||||
|
||||
@ -6,23 +6,20 @@ namespace Svrnty.CQRS.Abstractions.Discovery;
|
||||
|
||||
public class QueryMeta : IQueryMeta
|
||||
{
|
||||
private readonly string _name;
|
||||
|
||||
public QueryMeta(Type queryType, Type serviceType, Type queryResultType)
|
||||
{
|
||||
QueryType = queryType;
|
||||
ServiceType = serviceType;
|
||||
QueryResultType = queryResultType;
|
||||
|
||||
// Cache reflection and computed value once in constructor
|
||||
var nameAttribute = queryType.GetCustomAttribute<QueryNameAttribute>();
|
||||
_name = nameAttribute?.Name ?? queryType.Name.Replace("Query", string.Empty);
|
||||
}
|
||||
|
||||
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 string Name => _name;
|
||||
|
||||
public virtual Type QueryType { get; }
|
||||
public virtual Type ServiceType { get; }
|
||||
@ -33,13 +30,13 @@ public class QueryMeta : IQueryMeta
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(Name))
|
||||
return Name;
|
||||
|
||||
// Use virtual Name property so derived classes can override
|
||||
var name = Name;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return name;
|
||||
|
||||
var firstLetter = char.ToLowerInvariant(name[0]);
|
||||
var ret = $"{firstLetter}{name[1..]}";
|
||||
return ret;
|
||||
return $"{firstLetter}{name[1..]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,16 +7,37 @@ namespace Svrnty.CQRS.Discovery;
|
||||
|
||||
public sealed class CommandDiscovery : ICommandDiscovery
|
||||
{
|
||||
private readonly IEnumerable<ICommandMeta> _commandMetas;
|
||||
private readonly List<ICommandMeta> _commandMetas;
|
||||
private readonly Dictionary<string, ICommandMeta> _commandsByName;
|
||||
private readonly Dictionary<Type, ICommandMeta> _commandsByType;
|
||||
|
||||
public CommandDiscovery(IEnumerable<ICommandMeta> commandMetas)
|
||||
{
|
||||
_commandMetas = commandMetas;
|
||||
// Materialize the enumerable to a list once
|
||||
_commandMetas = commandMetas.ToList();
|
||||
|
||||
// Build lookup dictionaries for O(1) access
|
||||
_commandsByName = new Dictionary<string, ICommandMeta>(_commandMetas.Count);
|
||||
_commandsByType = new Dictionary<Type, ICommandMeta>(_commandMetas.Count);
|
||||
|
||||
foreach (var meta in _commandMetas)
|
||||
{
|
||||
_commandsByName[meta.Name] = meta;
|
||||
_commandsByType[meta.CommandType] = meta;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ICommandMeta> GetCommands() => _commandMetas;
|
||||
public ICommandMeta FindCommand(string name) => _commandMetas.FirstOrDefault(t => t.Name == name);
|
||||
public ICommandMeta FindCommand(Type commandType) => _commandMetas.FirstOrDefault(t => t.CommandType == commandType);
|
||||
public bool CommandExists(string name) => _commandMetas.Any(t => t.Name == name);
|
||||
public bool CommandExists(Type commandType) => _commandMetas.Any(t => t.CommandType == commandType);
|
||||
|
||||
public ICommandMeta FindCommand(string name) =>
|
||||
_commandsByName.TryGetValue(name, out var meta) ? meta : null;
|
||||
|
||||
public ICommandMeta FindCommand(Type commandType) =>
|
||||
_commandsByType.TryGetValue(commandType, out var meta) ? meta : null;
|
||||
|
||||
public bool CommandExists(string name) =>
|
||||
_commandsByName.ContainsKey(name);
|
||||
|
||||
public bool CommandExists(Type commandType) =>
|
||||
_commandsByType.ContainsKey(commandType);
|
||||
}
|
||||
|
||||
@ -7,17 +7,38 @@ namespace Svrnty.CQRS.Discovery;
|
||||
|
||||
public sealed class QueryDiscovery : IQueryDiscovery
|
||||
{
|
||||
private readonly IEnumerable<IQueryMeta> _queryMetas;
|
||||
private readonly List<IQueryMeta> _queryMetas;
|
||||
private readonly Dictionary<string, IQueryMeta> _queriesByName;
|
||||
private readonly Dictionary<Type, IQueryMeta> _queriesByType;
|
||||
|
||||
public QueryDiscovery(IEnumerable<IQueryMeta> queryMetas)
|
||||
{
|
||||
_queryMetas = queryMetas;
|
||||
// Materialize the enumerable to a list once
|
||||
_queryMetas = queryMetas.ToList();
|
||||
|
||||
// Build lookup dictionaries for O(1) access
|
||||
_queriesByName = new Dictionary<string, IQueryMeta>(_queryMetas.Count);
|
||||
_queriesByType = new Dictionary<Type, IQueryMeta>(_queryMetas.Count);
|
||||
|
||||
foreach (var meta in _queryMetas)
|
||||
{
|
||||
_queriesByName[meta.Name] = meta;
|
||||
_queriesByType[meta.QueryType] = meta;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IQueryMeta> GetQueries() => _queryMetas;
|
||||
public IQueryMeta FindQuery(string name) => _queryMetas.FirstOrDefault(t => t.Name == name);
|
||||
public IQueryMeta FindQuery(Type queryType) => _queryMetas.FirstOrDefault(t => t.QueryType == queryType);
|
||||
public bool QueryExists(string name) => _queryMetas.Any(t => t.Name == name);
|
||||
public bool QueryExists(Type queryType) => _queryMetas.Any(t => t.QueryType == queryType);
|
||||
|
||||
public IQueryMeta FindQuery(string name) =>
|
||||
_queriesByName.TryGetValue(name, out var meta) ? meta : null;
|
||||
|
||||
public IQueryMeta FindQuery(Type queryType) =>
|
||||
_queriesByType.TryGetValue(queryType, out var meta) ? meta : null;
|
||||
|
||||
public bool QueryExists(string name) =>
|
||||
_queriesByName.ContainsKey(name);
|
||||
|
||||
public bool QueryExists(Type queryType) =>
|
||||
_queriesByType.ContainsKey(queryType);
|
||||
}
|
||||
|
||||
|
||||
@ -22,13 +22,13 @@ public static class ServiceCollectionExtensions
|
||||
|
||||
public static IServiceCollection AddDefaultQueryDiscovery(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddTransient<IQueryDiscovery, QueryDiscovery>();
|
||||
services.TryAddSingleton<IQueryDiscovery, QueryDiscovery>();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddDefaultCommandDiscovery(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddTransient<ICommandDiscovery, CommandDiscovery>();
|
||||
services.TryAddSingleton<ICommandDiscovery, CommandDiscovery>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
1182
roadmap-2026/quick-analyze-improvements.md
Normal file
1182
roadmap-2026/quick-analyze-improvements.md
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user