PropertyAggregationBug #5
@ -7,9 +7,9 @@ root = true
|
||||
#### Core EditorConfig Options ####
|
||||
|
||||
# Indentation and spacing
|
||||
indent_size = 4
|
||||
indent_size = 3
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
tab_width = 3
|
||||
|
||||
# New line preferences
|
||||
end_of_line = crlf
|
||||
|
2
src/Connected.Caching/SR.Designer.cs
generated
2
src/Connected.Caching/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Caching {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Caching.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Caching.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
2
src/Connected.Collections/SR.Designer.cs
generated
2
src/Connected.Collections/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Collections {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Collections.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Collections.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
2
src/Connected.Entities/SR.Designer.cs
generated
2
src/Connected.Entities/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Entities {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Entities.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Entities.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
2
src/Connected.Hosting/SR.Designer.cs
generated
2
src/Connected.Hosting/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Hosting {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Hosting.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Hosting.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Connected.ServiceModel;
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Connected.Interop.Merging
|
||||
@ -11,7 +10,7 @@ namespace Connected.Interop.Merging
|
||||
if (destination is null || !HasSource(sources))
|
||||
return;
|
||||
|
||||
var sourceProperties = AggregateProperties(sources);
|
||||
var sourceProperties = PropertyAggregator.Aggregate(sources);
|
||||
|
||||
foreach (var property in Properties.GetImplementedProperties(destination))
|
||||
MergeProperty(destination, sourceProperties, property);
|
||||
@ -28,42 +27,6 @@ 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())
|
||||
@ -74,7 +37,8 @@ namespace Connected.Interop.Merging
|
||||
if (!sourceProperties.TryGetValue(property.Name, out object? source))
|
||||
return;
|
||||
|
||||
property.SetValue(destination, source.GetType().GetProperty(property.Name).GetValue(source));
|
||||
if (source.GetType() is Type propertyType && PropertyResolver.Resolve(propertyType, property.Name) is PropertyInfo propertyInfo)
|
||||
property.SetValue(destination, propertyInfo.GetValue(source));
|
||||
}
|
||||
else if (IsArray(property))
|
||||
MergeEnumerable(destination, sourceProperties, property);
|
||||
|
68
src/Connected.Interop/Merging/PropertyAggregator.cs
Normal file
68
src/Connected.Interop/Merging/PropertyAggregator.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using Connected.ServiceModel;
|
||||
|
||||
namespace Connected.Interop.Merging;
|
||||
internal static class PropertyAggregator
|
||||
{
|
||||
public static Dictionary<string, object> Aggregate(params object[] values)
|
||||
{
|
||||
var result = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
for (var i = values.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (values[i] is not object value)
|
||||
continue;
|
||||
|
||||
foreach (var property in GetImplementedProperties(value))
|
||||
{
|
||||
if (result.ContainsKey(property.Key))
|
||||
continue;
|
||||
|
||||
result.Add(property.Key, property.Value);
|
||||
}
|
||||
|
||||
if (value is IPropertyProvider provider)
|
||||
{
|
||||
foreach (var property in provider.Properties)
|
||||
{
|
||||
if (result.ContainsKey(property.Key))
|
||||
continue;
|
||||
|
||||
result.Add(property.Key, property.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<string, object> GetImplementedProperties(object value)
|
||||
{
|
||||
if (value is null)
|
||||
return new();
|
||||
|
||||
if (value is object[] objectArray)
|
||||
{
|
||||
var result = new Dictionary<string, object>();
|
||||
|
||||
for (var i = objectArray.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var implementations = Properties.GetImplementedProperties(objectArray[i]);
|
||||
|
||||
foreach (var property in implementations)
|
||||
result.Add(property.Name, objectArray[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
var implementations = Properties.GetImplementedProperties(value);
|
||||
var result = new Dictionary<string, object>();
|
||||
|
||||
foreach (var property in implementations)
|
||||
result.Add(property.Name, value);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
19
src/Connected.Interop/Merging/PropertyResolver.cs
Normal file
19
src/Connected.Interop/Merging/PropertyResolver.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Connected.Interop.Merging;
|
||||
internal static class PropertyResolver
|
||||
{
|
||||
public static PropertyInfo? Resolve(Type type, string propertyName)
|
||||
{
|
||||
if (type.GetProperty(propertyName) is PropertyInfo property)
|
||||
return property;
|
||||
|
||||
if (type.GetProperty(propertyName.ToCamelCase()) is PropertyInfo camelProperty)
|
||||
return camelProperty;
|
||||
|
||||
if (type.GetProperty(propertyName.ToPascalCase()) is PropertyInfo pascalProperty)
|
||||
return pascalProperty;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
2
src/Connected.Interop/SR.Designer.cs
generated
2
src/Connected.Interop/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Interop {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Interop.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Interop.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
2
src/Connected.Net/SR.Designer.cs
generated
2
src/Connected.Net/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Net {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Net.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Net.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
@ -1,37 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0-rc.2.22472.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Connected\src\Connected\Connected.csproj" />
|
||||
<ProjectReference Include="..\Connected.Configuration\Connected.Configuration.csproj" />
|
||||
<ProjectReference Include="..\Connected.Interop\Connected.Interop.csproj" />
|
||||
<ProjectReference Include="..\Connected.Net\Connected.Net.csproj" />
|
||||
<ProjectReference Include="..\Connected.Services\Connected.Services.csproj" />
|
||||
</ItemGroup>
|
||||
<ProjectReference Include="..\Connected.Configuration\Connected.Configuration.csproj" />
|
||||
<ProjectReference Include="..\Connected.Interop\Connected.Interop.csproj" />
|
||||
<ProjectReference Include="..\Connected.Net\Connected.Net.csproj" />
|
||||
<ProjectReference Include="..\Connected.Services\Connected.Services.csproj" />
|
||||
<ProjectReference Include="..\..\..\connected.framework\src\Connected.Runtime\Connected.Runtime.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="SR.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>SR.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="SR.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>SR.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="SR.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>SR.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="SR.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>SR.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
2
src/Connected.Security/SR.Designer.cs
generated
2
src/Connected.Security/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Security {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Security.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Security.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
2
src/Connected.Services/SR.Designer.cs
generated
2
src/Connected.Services/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Services {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Services.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Services.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
2
src/Connected.Threading/SR.Designer.cs
generated
2
src/Connected.Threading/SR.Designer.cs
generated
@ -39,7 +39,7 @@ namespace Connected.Threading {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server.Threading.SR", typeof(SR).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Connected.Threading.SR", typeof(SR).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
Loading…
x
Reference in New Issue
Block a user