|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using Connected.ServiceModel;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
|
|
|
|
namespace Connected.Interop.Merging
|
|
|
|
@ -10,7 +11,7 @@ namespace Connected.Interop.Merging
|
|
|
|
|
if (destination is null || !HasSource(sources))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var sourceProperties = PropertyAggregator.Aggregate(sources);
|
|
|
|
|
var sourceProperties = AggregateProperties(sources);
|
|
|
|
|
|
|
|
|
|
foreach (var property in Properties.GetImplementedProperties(destination))
|
|
|
|
|
MergeProperty(destination, sourceProperties, property);
|
|
|
|
@ -27,6 +28,42 @@ namespace Connected.Interop.Merging
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Dictionary<string, object> AggregateProperties(params object[] sources)
|
|
|
|
|
{
|
|
|
|
|
var result = new Dictionary<string, object>();
|
|
|
|
|
|
|
|
|
|
for (var i = sources.Length - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
var source = sources[i];
|
|
|
|
|
|
|
|
|
|
if (source is null)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
var props = Properties.GetImplementedProperties(source);
|
|
|
|
|
|
|
|
|
|
foreach (var property in props)
|
|
|
|
|
{
|
|
|
|
|
if (result.ContainsKey(property.Name))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
result.Add(property.Name, source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (source is IPropertyProvider provider)
|
|
|
|
|
{
|
|
|
|
|
foreach (var property in provider.Properties)
|
|
|
|
|
{
|
|
|
|
|
if (result.ContainsKey(property.Key))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
result.Add(property.Key, property.Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void MergeProperty(object destination, Dictionary<string, object> sourceProperties, PropertyInfo property)
|
|
|
|
|
{
|
|
|
|
|
if (property.PropertyType.IsTypePrimitive())
|
|
|
|
@ -37,8 +74,7 @@ namespace Connected.Interop.Merging
|
|
|
|
|
if (!sourceProperties.TryGetValue(property.Name, out object? source))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (source.GetType() is Type propertyType && PropertyResolver.Resolve(propertyType, property.Name) is PropertyInfo propertyInfo)
|
|
|
|
|
property.SetValue(destination, propertyInfo.GetValue(source));
|
|
|
|
|
property.SetValue(destination, source.GetType().GetProperty(property.Name).GetValue(source));
|
|
|
|
|
}
|
|
|
|
|
else if (IsArray(property))
|
|
|
|
|
MergeEnumerable(destination, sourceProperties, property);
|
|
|
|
|