using System.ComponentModel; using System.Linq.Expressions; using System.Runtime.CompilerServices; using NetinaShop.Common.Models.Exception; namespace NetinaShop.Common.Models.Mapper { /// /// Base Dto Class initial map config between entity and dto /// /// Type of Dto Class /// Type of Entity Class public abstract class BaseDto : INotifyPropertyChanged, IBaseDto where TEntity : class where TDto : class { public Guid Id { get; set; } public static Expression> ProjectToDto { get => GetProjectToDto(); } private static Expression> GetProjectToDto() { var assembly = typeof(TEntity).Assembly; var mapperName = $"{typeof(TEntity).Name}Mapper"; var mapperType = assembly.GetTypes()?.FirstOrDefault(t => t.Name.Contains(mapperName)); if (mapperType == null) throw new AppException($"{typeof(TEntity).Name}Mapper Not Found!"); if (typeof(TDto).Name.Contains("SDto")) { var projectProperty = mapperType.GetProperty("ProjectToSDto"); if (projectProperty == null) throw new AppException($"{typeof(TEntity).Name}Mapper Dont Have ProjectTo"); return projectProperty.GetValue(null, null) as Expression>; } else if (typeof(TDto).Name.Contains("LDto")) { var projectProperty = mapperType.GetProperty("ProjectToLDto"); if (projectProperty == null) throw new AppException($"{typeof(TEntity).Name}Mapper Dont Have ProjectTo"); return projectProperty.GetValue(null, null) as Expression>; } else throw new AppException($"{typeof(TDto).Name} Projection Not Implemented"); } public virtual bool Compare(object obj) { if(obj is BaseDto objDto) return objDto.Id == this.Id; return Equals(obj); } public TDto Clone() { return (TDto)MemberwiseClone(); } public TEntity ToEntity() { var assembly = typeof(TEntity).Assembly; var mapperName = $"{typeof(TEntity).Name}Mapper"; var mapperType = assembly.GetTypes()?.FirstOrDefault(t => t.Name.Contains(mapperName)); var toEntityMethodInfo = mapperType.GetMethod($"AdaptTo{typeof(TEntity).Name}"); var parms = new[] { this }; var entity = toEntityMethodInfo.Invoke(null, parms); if (entity is TEntity o) return o; return null; } public static TDto FromEntity(TEntity model) { var assembly = typeof(TEntity).Assembly; var mapperName = $"{typeof(TEntity).Name}Mapper"; var mapperType = assembly.GetTypes()?.FirstOrDefault(t => t.Name.Contains(mapperName)); var toDtoMethodInfo = mapperType.GetMethod("AdaptToDto"); var parms = new[] { model }; var dto = toDtoMethodInfo.Invoke(null, parms); if (dto is TDto o) return o; return null; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected bool SetField(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } } }