using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
{
///
/// Base class for value objects in domain.
/// Value
///
/// The type of this value object
public class ValueObject : IEquatable
where TValueObject : ValueObject
{
//IEquatable and Override Equals operators
///
///
///
///
///
public bool Equals(TValueObject other)
{
if ((object)other == null)
return false;
if (Object.ReferenceEquals(this, other))
return true;
//compare all public properties
PropertyInfo[] publicProperties = this.GetType().GetProperties();
if ((object)publicProperties != null
&&
publicProperties.Any())
{
return publicProperties.All(p =>
{
var left = p.GetValue(this, null);
var right = p.GetValue(other, null);
if (typeof(TValueObject).IsAssignableFrom(left.GetType()))
{
//check not self-references...
return Object.ReferenceEquals(left, right);
}
else
return left.Equals(right);
});
}
else
return true;
}
///
///
///
///
///
public override bool Equals(object obj)
{
if ((object)obj == null)
return false;
if (Object.ReferenceEquals(this, obj))
return true;
ValueObject item = obj as ValueObject;
if ((object)item != null)
return Equals((TValueObject)item);
else
return false;
}
///
///
///
///
public override int GetHashCode()
{
int hashCode = 31;
bool changeMultiplier = false;
int index = 1;
//compare all public properties
PropertyInfo[] publicProperties = this.GetType().GetProperties();
if ((object)publicProperties != null
&&
publicProperties.Any())
{
foreach (var item in publicProperties)
{
object value = item.GetValue(this, null);
if ((object)value != null)
{
hashCode = hashCode * ((changeMultiplier) ? 59 : 114) + value.GetHashCode();
changeMultiplier = !changeMultiplier;
}
else
hashCode = hashCode ^ (index * 13);//only for support {"a",null,null,"a"} <> {null,"a","a",null}
}
}
return hashCode;
}
///
///
///
///
///
///
public static bool operator ==(ValueObject left, ValueObject right)
{
if (Object.Equals(left, null))
return (Object.Equals(right, null)) ? true : false;
else
return left.Equals(right);
}
///
///
///
///
///
///
public static bool operator !=(ValueObject left, ValueObject right)
{
return !(left == right);
}
}
}