Fixed configuration to allow merge of new data into existing data

This commit is contained in:
TheXamlGuy
2024-10-03 16:35:34 +01:00
parent 855edf7d6d
commit 8136739372
5 changed files with 78 additions and 8 deletions
+25 -1
View File
@@ -22,7 +22,7 @@ public class Component :
return factory.Create<TComponent>(builder); return factory.Create<TComponent>(builder);
} }
public IComponentBuilder Configure(string? name = null, public IComponentBuilder Configure(string name,
Action<IComponentBuilder>? builderDelegate = null) Action<IComponentBuilder>? builderDelegate = null)
{ {
if (builderDelegate is not null) if (builderDelegate is not null)
@@ -33,5 +33,29 @@ public class Component :
return Configuring(builder); return Configuring(builder);
} }
public IComponentBuilder Configure(Action<IComponentBuilder>? builderDelegate = null)
{
if (builderDelegate is not null)
{
builderDelegate(builder);
}
return Configuring(builder);
}
public IComponentBuilder Configure<TConfiguration>(string name,
TConfiguration? configuration = null,
Action<IComponentBuilder>? builderDelegate = null)
where TConfiguration : class, new()
{
if (builderDelegate is not null)
{
builderDelegate(builder);
}
builder.AddConfiguration(name, configuration);
return Configuring(builder);
}
public virtual IComponentBuilder Configuring(IComponentBuilder builder) => builder; public virtual IComponentBuilder Configuring(IComponentBuilder builder) => builder;
} }
+1 -2
View File
@@ -16,7 +16,7 @@ public class ComponentFactory(IServiceProvider provider,
{ {
if (provider.GetRequiredService<TComponent>() is TComponent component) if (provider.GetRequiredService<TComponent>() is TComponent component)
{ {
IComponentBuilder builder = component.Configure(name, builderDelegate); IComponentBuilder builder = component.Configure(name, configuration, builderDelegate);
builder.AddServices(services => builder.AddServices(services =>
{ {
@@ -42,7 +42,6 @@ public class ComponentFactory(IServiceProvider provider,
services.AddSingleton(new NamedComponent(name)); services.AddSingleton(new NamedComponent(name));
}); });
builder.AddConfiguration(name, configuration);
IComponentHost host = builder.Build(); IComponentHost host = builder.Build();
scopes.Add(new ComponentScopeDescriptor(name, scopes.Add(new ComponentScopeDescriptor(name,
+43 -4
View File
@@ -13,8 +13,6 @@ public class ConfigurationSource<TConfiguration>(IConfigurationFile<TConfigurati
where TConfiguration : where TConfiguration :
class class
{ {
private readonly object lockingObject = new();
private static readonly Func<JsonSerializerOptions> defaultSerializerOptions = new(() => private static readonly Func<JsonSerializerOptions> defaultSerializerOptions = new(() =>
{ {
return new JsonSerializerOptions return new JsonSerializerOptions
@@ -30,6 +28,8 @@ public class ConfigurationSource<TConfiguration>(IConfigurationFile<TConfigurati
}; };
}); });
private readonly object lockingObject = new();
public void Set(TConfiguration value) => Set((object)value); public void Set(TConfiguration value) => Set((object)value);
public void Set(object value) public void Set(object value)
@@ -92,12 +92,12 @@ public class ConfigurationSource<TConfiguration>(IConfigurationFile<TConfigurati
} }
else else
{ {
array[index] = valueNode; array[index] = MergeNodes(array[index], valueNode);
} }
} }
else else
{ {
currentNode[lastKey] = valueNode; currentNode[lastKey] = MergeNodes(currentNode[lastKey], valueNode);
} }
} }
@@ -159,4 +159,43 @@ public class ConfigurationSource<TConfiguration>(IConfigurationFile<TConfigurati
return false; return false;
} }
} }
private JsonNode? CloneNode(JsonNode? node)
{
if (node is null)
{
return null;
}
string serialized = JsonSerializer.Serialize(node, serializerOptions ?? defaultSerializerOptions());
return JsonNode.Parse(serialized);
}
private JsonNode? MergeNodes(JsonNode? existingNode, JsonNode? newNode)
{
newNode = CloneNode(newNode);
if (existingNode is JsonObject existingObject && newNode is JsonObject newObject)
{
foreach (KeyValuePair<string, JsonNode?> property in newObject)
{
existingObject[property.Key] = MergeNodes(existingObject[property.Key], property.Value);
}
return existingObject;
}
else if (existingNode is JsonArray existingArray && newNode is JsonArray newArray)
{
foreach (JsonNode? item in newArray)
{
existingArray.Add(item);
}
return existingArray;
}
else
{
return newNode;
}
}
} }
+8 -1
View File
@@ -2,6 +2,13 @@
public interface IComponent public interface IComponent
{ {
IComponentBuilder Configure(string? name = null, IComponentBuilder Configure(string name,
Action<IComponentBuilder>? builderDelegate = null); Action<IComponentBuilder>? builderDelegate = null);
IComponentBuilder Configure(Action<IComponentBuilder>? builderDelegate = null);
IComponentBuilder Configure<TConfiguration>(string name,
TConfiguration? configuration = null,
Action<IComponentBuilder>? builderDelegate = null)
where TConfiguration : class, new();
} }
@@ -6,6 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
<PackageReference Include="JsonPatch.Net" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-rc.1.24431.7" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-rc.1.24431.7" />
<PackageReference Include="System.Reactive" Version="6.0.1" /> <PackageReference Include="System.Reactive" Version="6.0.1" />
</ItemGroup> </ItemGroup>