// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.Persistence; using System.Collections.Concurrent; using System.Reflection; using MUnique.OpenMU.Interfaces; /// /// Extensions for objects. /// public static class ObjectExtensions { private static readonly ConcurrentDictionary IdProperties = new(); private static readonly ConcurrentDictionary NameProperties = new(); /// /// Gets the guid identifier of an object, which has the name "Id". /// /// The item. /// The guid identifier of an object, which has the name "Id". public static Guid GetId(this object item) { if (item is IIdentifiable identifiable) { return identifiable.Id; } if (!IdProperties.TryGetValue(item.GetType(), out var idProperty)) { idProperty = item.GetType().GetProperties().FirstOrDefault(p => p.Name.Equals("Id") && p.PropertyType == typeof(Guid)); IdProperties.TryAdd(item.GetType(), idProperty); } if (idProperty is null) { return Guid.Empty; } return (Guid)idProperty.GetValue(item)!; } /// /// Gets the name of an object. /// /// The item. /// The name of an object. public static string GetName(this object item) { if (!NameProperties.TryGetValue(item.GetType(), out var nameProperty)) { var properties = item.GetType().GetProperties() .Where(p => p.PropertyType == typeof(string) || p.PropertyType == typeof(LocalizedString)) .ToList(); nameProperty = properties.FirstOrDefault(p => p.Name.Equals("Name")) ?? properties.FirstOrDefault(p => p.Name.Equals("Caption")) ?? properties.FirstOrDefault(p => p.Name.Equals("Designation")) ?? properties.FirstOrDefault(p => p.Name.Equals("Description")); NameProperties.TryAdd(item.GetType(), nameProperty); } if (nameProperty is null) { return item.ToString() ?? string.Empty; } var result = nameProperty.GetValue(item) switch { LocalizedString localizedString => localizedString.ToString(), string str => str!, null => string.Empty, _ => item.ToString(), }; return result ?? string.Empty; } }