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