136 lines
4.3 KiB
C#
136 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using FSI.Lib.CompareNetObjects.TypeComparers;
|
|
using System.Reflection;
|
|
|
|
namespace FSI.Lib.CompareNetObjects
|
|
{
|
|
/// <summary>
|
|
/// The base comparer which contains all the type comparers
|
|
/// </summary>
|
|
public class RootComparer : BaseComparer
|
|
{
|
|
#region Properties
|
|
|
|
|
|
/// <summary>
|
|
/// A list of the type comparers
|
|
/// </summary>
|
|
internal List<BaseTypeComparer> TypeComparers { get; set; }
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
/// <summary>
|
|
/// Compare two objects
|
|
/// </summary>
|
|
public bool Compare(CompareParms parms)
|
|
{
|
|
try
|
|
{
|
|
if (parms.Object1 == null && parms.Object2 == null)
|
|
return true;
|
|
|
|
Type t1 = parms.Object1 != null ? parms.Object1.GetType() : null;
|
|
Type t2 = parms.Object2 != null ? parms.Object2.GetType() : null;
|
|
|
|
if (ExcludeLogic.ShouldExcludeType(parms.Config, t1, t2))
|
|
return true;
|
|
|
|
BaseTypeComparer customComparer = parms.Config.CustomComparers.FirstOrDefault(o => o.IsTypeMatch(t1, t2));
|
|
|
|
if (customComparer != null)
|
|
{
|
|
customComparer.CompareType(parms);
|
|
}
|
|
else if (parms.CustomPropertyComparer != null)
|
|
{
|
|
parms.CustomPropertyComparer.CompareType(parms);
|
|
}
|
|
else
|
|
{
|
|
BaseTypeComparer typeComparer = TypeComparers.FirstOrDefault(o => o.IsTypeMatch(t1, t2));
|
|
|
|
if (typeComparer != null)
|
|
{
|
|
if (parms.Config.IgnoreObjectTypes || !TypesDifferent(parms, t1, t2))
|
|
{
|
|
typeComparer.CompareType(parms);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (EitherObjectIsNull(parms)) return false;
|
|
|
|
if (!parms.Config.IgnoreObjectTypes && t1 != null)
|
|
throw new NotSupportedException("Cannot compare object of type " + t1.Name);
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (ObjectDisposedException)
|
|
{
|
|
if (!parms.Config.IgnoreObjectDisposedException)
|
|
throw;
|
|
|
|
return true;
|
|
}
|
|
|
|
return parms.Result.AreEqual;
|
|
}
|
|
|
|
private bool TypesDifferent(CompareParms parms, Type t1, Type t2)
|
|
{
|
|
//Objects must be the same type and not be null
|
|
if (!parms.Config.IgnoreObjectTypes
|
|
&& parms.Object1 != null
|
|
&& parms.Object2 != null
|
|
&& t1 != t2)
|
|
{
|
|
//Only care if they are in the same inheritance hierarchy or decleared as the same interface.
|
|
if (parms.Config.IgnoreConcreteTypes
|
|
&& (parms.Object1DeclaredType != null
|
|
&& parms.Object2DeclaredType != null
|
|
&& parms.Object1DeclaredType == parms.Object2DeclaredType
|
|
|| (t1.IsAssignableFrom(t2) || t2.IsAssignableFrom(t1))))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Difference difference = new Difference
|
|
{
|
|
ParentObject1 = parms.ParentObject1,
|
|
ParentObject2 = parms.ParentObject2,
|
|
PropertyName = parms.BreadCrumb,
|
|
Object1Value = t1.FullName,
|
|
Object2Value = t2.FullName,
|
|
ChildPropertyName = "GetType()",
|
|
MessagePrefix = "Different Types",
|
|
Object1 = parms.Object1,
|
|
Object2 = parms.Object2
|
|
};
|
|
|
|
AddDifference(parms.Result, difference);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool EitherObjectIsNull(CompareParms parms)
|
|
{
|
|
//Check if one of them is null
|
|
if (parms.Object1 == null || parms.Object2 == null)
|
|
{
|
|
AddDifference(parms);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|