Browse Source

feat: Add DynamicsCore Module

pull/1565/head
colin 2 weeks ago
parent
commit
10bf53dbec
  1. 3
      aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/FodyWeavers.xml
  2. 30
      aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/FodyWeavers.xsd
  3. 20
      aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN.Abp.Dynamic.Definitions.Core.csproj
  4. 8
      aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/AbpDynamicDefinitionsCoreModule.cs
  5. 35
      aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/AbpDynamicDefinitionsOptions.cs
  6. 240
      aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/DynamicDefinitionManager.cs
  7. 8
      aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/DynamicDefinitionStrategy.cs

3
aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

20
aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN.Abp.Dynamic.Definitions.Core.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0;net10.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.Dynamic.Definitions.Core</AssemblyName>
<PackageId>LINGYUN.Abp.Dynamic.Definitions.Core</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" />
</ItemGroup>
</Project>

8
aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/AbpDynamicDefinitionsCoreModule.cs

@ -0,0 +1,8 @@
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Dynamic.Definitions;
public class AbpDynamicDefinitionsCoreModule : AbpModule
{
}

35
aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/AbpDynamicDefinitionsOptions.cs

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.Dynamic.Definitions;
public class AbpDynamicDefinitionsOptions
{
public DynamicDefinitionStrategy DefaultStrategy { get; set; }
public Dictionary<Type, DynamicDefinitionStrategy> DefinitionStrategy { get; set; }
public AbpDynamicDefinitionsOptions()
{
DefaultStrategy = DynamicDefinitionStrategy.Static;
DefinitionStrategy = new Dictionary<Type, DynamicDefinitionStrategy>();
}
public void MapStrategy<T>(DynamicDefinitionStrategy strategy = DynamicDefinitionStrategy.Static)
{
DefinitionStrategy[typeof(T)] = strategy;
}
public DynamicDefinitionStrategy GetStrategy<T>()
{
return GetStrategy(typeof(T));
}
public DynamicDefinitionStrategy GetStrategy(Type type)
{
if (DefinitionStrategy.TryGetValue(type, out var strategy))
{
return strategy;
}
return DefaultStrategy;
}
}

240
aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/DynamicDefinitionManager.cs

@ -0,0 +1,240 @@
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Dynamic.Definitions;
public abstract class DynamicDefinitionManager<TGroupDefinition, TDefinition> : DynamicDefinitionManager<TDefinition>
{
protected DynamicDefinitionManager(
IOptions<AbpDynamicDefinitionsOptions> options) : base(options)
{
}
public async virtual Task<TGroupDefinition?> GetGroupDefinitionAsync(
TGroupDefinition? staticGroupDefinition,
TGroupDefinition? dynamicGroupDefinition)
{
if (staticGroupDefinition != null && dynamicGroupDefinition != null)
{
var strategy = Options.GetStrategy<TGroupDefinition>();
switch (strategy)
{
case DynamicDefinitionStrategy.Dynamic:
return dynamicGroupDefinition;
case DynamicDefinitionStrategy.Merge:
await MergeGroupDefinitionAsync(staticGroupDefinition, dynamicGroupDefinition);
return staticGroupDefinition;
case DynamicDefinitionStrategy.Static:
default:
return staticGroupDefinition;
}
}
return staticGroupDefinition ?? dynamicGroupDefinition;
}
public async virtual Task<IReadOnlyList<TGroupDefinition>> GetGroupDefinitionsAsync(
IReadOnlyList<TGroupDefinition> staticGroupDefinitions,
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions)
{
var strategy = Options.GetStrategy<TGroupDefinition>();
return strategy switch
{
DynamicDefinitionStrategy.Dynamic => await GetDynamicGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions),
DynamicDefinitionStrategy.Merge => await GetMergedGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions),
_ => await GetStaticGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions),
};
}
protected virtual Task<IReadOnlyList<TGroupDefinition>> GetStaticGroupDefinitionsAsync(
IReadOnlyList<TGroupDefinition> staticGroupDefinitions,
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions)
{
var staticDefinitionKeys = staticGroupDefinitions
.Select(GetGroupDefinitionKey)
.ToImmutableHashSet();
return Task.FromResult<IReadOnlyList<TGroupDefinition>>(
staticGroupDefinitions
.Concat(dynamicGroupDefinitions.Where(d => !staticDefinitionKeys.Contains(GetGroupDefinitionKey(d))))
.ToImmutableList()
);
}
protected virtual Task<IReadOnlyList<TGroupDefinition>> GetDynamicGroupDefinitionsAsync(
IReadOnlyList<TGroupDefinition> staticGroupDefinitions,
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions)
{
var dynamicDefinitionKeys = dynamicGroupDefinitions
.Select(GetGroupDefinitionKey)
.ToImmutableHashSet();
return Task.FromResult<IReadOnlyList<TGroupDefinition>>(
dynamicGroupDefinitions
.Concat(staticGroupDefinitions.Where(s => !dynamicDefinitionKeys.Contains(GetGroupDefinitionKey(s))))
.ToImmutableList()
);
}
protected async virtual Task<IReadOnlyList<TGroupDefinition>> GetMergedGroupDefinitionsAsync(
IReadOnlyList<TGroupDefinition> staticGroupDefinitions,
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions)
{
var mergedGroups = new Dictionary<string, TGroupDefinition>();
foreach (var staticGroup in staticGroupDefinitions)
{
mergedGroups[GetGroupDefinitionKey(staticGroup)] = staticGroup;
}
foreach (var dynamicGroup in dynamicGroupDefinitions)
{
if (mergedGroups.TryGetValue(GetGroupDefinitionKey(dynamicGroup), out var existingGroup))
{
await BeforeMergeGroupDefinitionAsync(existingGroup, dynamicGroup);
await MergeGroupDefinitionAsync(existingGroup, dynamicGroup);
await AfterMergeGroupDefinitionAsync(existingGroup, dynamicGroup);
}
else
{
mergedGroups[GetGroupDefinitionKey(dynamicGroup)] = dynamicGroup;
}
}
await AfterMergedGroupDefinitionsAsync(mergedGroups);
return mergedGroups.Values.ToImmutableList();
}
protected abstract string GetGroupDefinitionKey(TGroupDefinition groupDefinition);
protected abstract Task MergeGroupDefinitionAsync(TGroupDefinition targetGroupDefinition, TGroupDefinition sourceGroupDefinition);
protected virtual Task BeforeMergeGroupDefinitionAsync(TGroupDefinition targetGroupDefinition, TGroupDefinition sourceGroupDefinition)
{
return Task.CompletedTask;
}
protected virtual Task AfterMergeGroupDefinitionAsync(TGroupDefinition targetGroupDefinition, TGroupDefinition sourceGroupDefinition)
{
return Task.CompletedTask;
}
protected virtual Task AfterMergedGroupDefinitionsAsync(Dictionary<string, TGroupDefinition> mergedDefinitions)
{
return Task.CompletedTask;
}
}
public abstract class DynamicDefinitionManager<TDefinition>
{
protected AbpDynamicDefinitionsOptions Options { get; }
protected DynamicDefinitionManager(IOptions<AbpDynamicDefinitionsOptions> options)
{
Options = options.Value;
}
public async virtual Task<TDefinition?> GetDefinitionAsync(TDefinition? staticDefinition, TDefinition? dynamicDefinition)
{
if (staticDefinition != null && dynamicDefinition != null)
{
var strategy = Options.GetStrategy<TDefinition>();
return strategy switch
{
DynamicDefinitionStrategy.Static => staticDefinition,
DynamicDefinitionStrategy.Dynamic => dynamicDefinition,
DynamicDefinitionStrategy.Merge => await MergeDefinitionAsync(staticDefinition, dynamicDefinition),
_ => staticDefinition
};
}
return staticDefinition ?? dynamicDefinition;
}
public async virtual Task<IReadOnlyList<TDefinition>> GetDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions)
{
var strategy = Options.GetStrategy<TDefinition>();
return strategy switch
{
DynamicDefinitionStrategy.Dynamic => await GetDynamicDefinitionsAsync(staticDefinitions, dynamicDefinitions),
DynamicDefinitionStrategy.Merge => await GetMergedDefinitionsAsync(staticDefinitions, dynamicDefinitions),
_ => await GetStaticDefinitionsAsync(staticDefinitions, dynamicDefinitions),
};
}
protected virtual Task<IReadOnlyList<TDefinition>> GetStaticDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions)
{
var staticDefinitionKeys = staticDefinitions
.Select(GetDefinitionKey)
.ToImmutableHashSet();
return Task.FromResult<IReadOnlyList<TDefinition>>(
staticDefinitions
.Concat(dynamicDefinitions.Where(d => !staticDefinitionKeys.Contains(GetDefinitionKey(d))))
.ToImmutableList()
);
}
protected virtual Task<IReadOnlyList<TDefinition>> GetDynamicDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions)
{
var dynamicDefinitionKeys = dynamicDefinitions
.Select(GetDefinitionKey)
.ToImmutableHashSet();
return Task.FromResult<IReadOnlyList<TDefinition>>(
dynamicDefinitions
.Concat(staticDefinitions.Where(s => !dynamicDefinitionKeys.Contains(GetDefinitionKey(s))))
.ToImmutableList()
);
}
protected async virtual Task<IReadOnlyList<TDefinition>> GetMergedDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions)
{
var mergedDefinitions = new Dictionary<string, TDefinition>();
foreach (var staticDefinition in staticDefinitions)
{
mergedDefinitions[GetDefinitionKey(staticDefinition)] = staticDefinition;
}
foreach (var dynamicDefinition in dynamicDefinitions)
{
if (mergedDefinitions.TryGetValue(GetDefinitionKey(dynamicDefinition), out var existingDefinition))
{
await BeforeMergeDefinitionAsync(existingDefinition, dynamicDefinition);
await MergeDefinitionAsync(existingDefinition, dynamicDefinition);
await AfterMergeDefinitionAsync(existingDefinition, dynamicDefinition);
}
else
{
mergedDefinitions[GetDefinitionKey(dynamicDefinition)] = dynamicDefinition;
}
}
await AfterMergedDefinitionsAsync(mergedDefinitions);
return mergedDefinitions.Values.ToImmutableList();
}
protected abstract string GetDefinitionKey(TDefinition definition);
protected abstract Task<TDefinition> MergeDefinitionAsync(TDefinition targetDefinition, TDefinition sourceDefinition);
protected virtual Task BeforeMergeDefinitionAsync(TDefinition targetDefinition, TDefinition sourceDefinition)
{
return Task.CompletedTask;
}
protected virtual Task AfterMergeDefinitionAsync(TDefinition targetDefinition, TDefinition sourceDefinition)
{
return Task.CompletedTask;
}
protected virtual Task AfterMergedDefinitionsAsync(Dictionary<string, TDefinition> mergedDefinitions)
{
return Task.CompletedTask;
}
}

8
aspnet-core/framework/dynamic-definition/LINGYUN.Abp.Dynamic.Definitions.Core/LINGYUN/Abp/Dynamic/Definitions/DynamicDefinitionStrategy.cs

@ -0,0 +1,8 @@
namespace LINGYUN.Abp.Dynamic.Definitions;
public enum DynamicDefinitionStrategy
{
Static = 0,
Dynamic = 1,
Merge = 2,
}
Loading…
Cancel
Save