using System.ComponentModel.DataAnnotations.Schema; using System.Reflection; using System.Text.RegularExpressions; namespace ReC.Application.Common.Dto; public static partial class PlaceholderExtensions { [GeneratedRegex(@"\{#[^#]+#[^}]+\}")] private static partial Regex PlaceholderRegex(); /// /// Replaces placeholders in the format {#ANY_STRING#COLUMN_NAME} with the corresponding /// property value resolved via from the provided objects. /// Values are converted to SQL-compatible string representations. /// If a placeholder cannot be resolved, it is replaced with NULL. /// public static string ReplacePlaceholders(this string str, params object?[] objects) { return PlaceholderRegex().Replace(str, match => { var placeholder = match.Value; var inner = placeholder[2..^1]; // remove {# and } var lastHash = inner.LastIndexOf('#'); var columnName = inner[(lastHash + 1)..]; foreach (var obj in objects) { if (obj is null) continue; var value = obj.GetValueByColumnName(columnName); if (value is not null) return ToSqlLiteral(value); } return "NULL"; }); } private static string ToSqlLiteral(object value) => value switch { bool b => b ? "TRUE" : "FALSE", DateTime dt => dt.ToString("yyyy-MM-dd HH:mm:ss"), DateTimeOffset dto => dto.ToString("yyyy-MM-dd HH:mm:ss zzz"), _ => value.ToString() ?? string.Empty }; /// /// Gets the value of a property by its column name defined in . /// Returns null if no property with the given column name exists. /// public static object? GetValueByColumnName(this T obj, string columnName) where T : class { var property = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(p => p.GetCustomAttribute()?.Name == columnName); return property?.GetValue(obj); } }