8 changed files with 775 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -0,0 +1,27 @@ |
|||
<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</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Dynamic.Definitions</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Authorization" /> |
|||
<PackageReference Include="Volo.Abp.Features" /> |
|||
<PackageReference Include="Volo.Abp.Settings" /> |
|||
<PackageReference Include="Volo.Abp.TextTemplating.Core" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Dynamic.Definitions.Core\LINGYUN.Abp.Dynamic.Definitions.Core.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,32 @@ |
|||
using Volo.Abp.Authorization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpFeaturesModule), |
|||
typeof(AbpAuthorizationModule), |
|||
typeof(AbpTextTemplatingCoreModule), |
|||
typeof(AbpDynamicDefinitionsCoreModule))] |
|||
public class AbpDynamicDefinitionsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpDynamicDefinitionsOptions>(options => |
|||
{ |
|||
options.MapStrategy<FeatureDefinition>(DynamicDefinitionStrategy.Merge); |
|||
options.MapStrategy<FeatureGroupDefinition>(DynamicDefinitionStrategy.Merge); |
|||
|
|||
options.MapStrategy<PermissionDefinition>(DynamicDefinitionStrategy.Merge); |
|||
options.MapStrategy<PermissionGroupDefinition>(DynamicDefinitionStrategy.Merge); |
|||
|
|||
options.MapStrategy<SettingDefinition>(DynamicDefinitionStrategy.Merge); |
|||
|
|||
options.MapStrategy<TemplateDefinition>(DynamicDefinitionStrategy.Merge); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,253 @@ |
|||
using JetBrains.Annotations; |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(IFeatureDefinitionManager), |
|||
typeof(FeatureDynamicDefinitionManager))] |
|||
public class FeatureDynamicDefinitionManager : |
|||
DynamicDefinitionManager<FeatureGroupDefinition, FeatureDefinition>, |
|||
IFeatureDefinitionManager, |
|||
ISingletonDependency |
|||
{ |
|||
protected IStaticFeatureDefinitionStore StaticStore { get; } |
|||
protected IDynamicFeatureDefinitionStore DynamicStore { get; } |
|||
public FeatureDynamicDefinitionManager( |
|||
IStaticFeatureDefinitionStore staticStore, |
|||
IDynamicFeatureDefinitionStore dynamicStore, |
|||
IOptions<AbpDynamicDefinitionsOptions> options) |
|||
: base(options) |
|||
{ |
|||
StaticStore = staticStore; |
|||
DynamicStore = dynamicStore; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<FeatureDefinition> GetAsync(string name) |
|||
{ |
|||
return await GetOrNullAsync(name) ?? throw new AbpException("Undefined feature: " + name); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroupDefinitions = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroupDefinitions = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
return await GetGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<FeatureDefinition?> GetOrNullAsync(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetOrNullAsync(name); |
|||
var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
protected override string GetDefinitionKey(FeatureDefinition definition) |
|||
{ |
|||
return definition.Name; |
|||
} |
|||
|
|||
protected override string GetGroupDefinitionKey(FeatureGroupDefinition groupDefinition) |
|||
{ |
|||
return groupDefinition.Name; |
|||
} |
|||
|
|||
protected override Task<FeatureDefinition> MergeDefinitionAsync(FeatureDefinition targetDefinition, FeatureDefinition sourceDefinition) |
|||
{ |
|||
targetDefinition.DisplayName = sourceDefinition.DisplayName; |
|||
|
|||
if (sourceDefinition.Description != null) |
|||
{ |
|||
targetDefinition.Description = sourceDefinition.Description; |
|||
} |
|||
|
|||
if (sourceDefinition.DefaultValue != null) |
|||
{ |
|||
targetDefinition.DefaultValue = sourceDefinition.DefaultValue; |
|||
} |
|||
|
|||
if (sourceDefinition.ValueType != null) |
|||
{ |
|||
targetDefinition.ValueType = sourceDefinition.ValueType; |
|||
} |
|||
|
|||
targetDefinition.IsVisibleToClients = targetDefinition.IsVisibleToClients || sourceDefinition.IsVisibleToClients; |
|||
targetDefinition.IsAvailableToHost = targetDefinition.IsAvailableToHost || sourceDefinition.IsAvailableToHost; |
|||
|
|||
CopyFeatureDetails(targetDefinition, sourceDefinition); |
|||
|
|||
return Task.FromResult(targetDefinition); |
|||
} |
|||
|
|||
protected async override Task AfterMergeDefinitionAsync(FeatureDefinition targetDefinition, FeatureDefinition sourceDefinition) |
|||
{ |
|||
foreach (var child in sourceDefinition.Children) |
|||
{ |
|||
await MergeChildFeature(targetDefinition, child); |
|||
} |
|||
} |
|||
|
|||
protected async override Task MergeGroupDefinitionAsync(FeatureGroupDefinition targetGroupDefinition, FeatureGroupDefinition sourceGroupDefinition) |
|||
{ |
|||
if (sourceGroupDefinition.DisplayName != null) |
|||
{ |
|||
targetGroupDefinition.DisplayName = sourceGroupDefinition.DisplayName; |
|||
} |
|||
foreach (var property in sourceGroupDefinition.Properties) |
|||
{ |
|||
targetGroupDefinition.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var sourceFeature in sourceGroupDefinition.Features) |
|||
{ |
|||
var existingFeature = GetFeatureOrNull(targetGroupDefinition, sourceFeature.Name); |
|||
|
|||
if (existingFeature == null) |
|||
{ |
|||
var newFeature = targetGroupDefinition.AddFeature( |
|||
sourceFeature.Name, |
|||
sourceFeature.DefaultValue, |
|||
sourceFeature.DisplayName, |
|||
sourceFeature.Description, |
|||
sourceFeature.ValueType, |
|||
sourceFeature.IsVisibleToClients, |
|||
sourceFeature.IsAvailableToHost |
|||
); |
|||
|
|||
CopyFeatureDetails(sourceFeature, newFeature); |
|||
|
|||
foreach (var child in sourceFeature.Children) |
|||
{ |
|||
AddChildFeatureRecursively(newFeature, child); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
await MergeDefinitionAsync(existingFeature, sourceFeature); |
|||
|
|||
foreach (var child in sourceFeature.Children) |
|||
{ |
|||
await MergeChildFeature(existingFeature, child); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private async Task MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) |
|||
{ |
|||
var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); |
|||
|
|||
if (existingChild == null) |
|||
{ |
|||
var newChild = parent.CreateChild( |
|||
sourceChild.Name, |
|||
sourceChild.DefaultValue, |
|||
sourceChild.DisplayName, |
|||
sourceChild.Description, |
|||
sourceChild.ValueType, |
|||
sourceChild.IsVisibleToClients, |
|||
sourceChild.IsAvailableToHost |
|||
); |
|||
CopyFeatureDetails(sourceChild, newChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
AddChildFeatureRecursively(newChild, grandchild); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
await MergeDefinitionAsync(existingChild, sourceChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
await MergeChildFeature(existingChild, grandchild); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) |
|||
{ |
|||
var newChild = parent.CreateChild( |
|||
sourceChild.Name, |
|||
sourceChild.DefaultValue, |
|||
sourceChild.DisplayName, |
|||
sourceChild.Description, |
|||
sourceChild.ValueType, |
|||
sourceChild.IsVisibleToClients, |
|||
sourceChild.IsAvailableToHost |
|||
); |
|||
|
|||
CopyFeatureDetails(sourceChild, newChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
AddChildFeatureRecursively(newChild, grandchild); |
|||
} |
|||
} |
|||
|
|||
private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) |
|||
{ |
|||
foreach (var property in source.Properties) |
|||
{ |
|||
target.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var provider in source.AllowedProviders) |
|||
{ |
|||
if (!target.AllowedProviders.Contains(provider)) |
|||
{ |
|||
target.AllowedProviders.Add(provider); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public static FeatureDefinition? GetFeatureOrNull( |
|||
FeatureGroupDefinition group, |
|||
[NotNull] string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
return GetFeatureOrNullRecursively(group.Features, name); |
|||
} |
|||
|
|||
private static FeatureDefinition? GetFeatureOrNullRecursively( |
|||
IReadOnlyList<FeatureDefinition> features, |
|||
string name) |
|||
{ |
|||
foreach (var feature in features) |
|||
{ |
|||
if (feature.Name == name) |
|||
{ |
|||
return feature; |
|||
} |
|||
|
|||
var childFeature = GetFeatureOrNullRecursively(feature.Children, name); |
|||
if (childFeature != null) |
|||
{ |
|||
return childFeature; |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
@ -0,0 +1,249 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(IPermissionDefinitionManager), |
|||
typeof(PermissionDynamicDefinitionManager))] |
|||
public class PermissionDynamicDefinitionManager : |
|||
DynamicDefinitionManager<PermissionGroupDefinition, PermissionDefinition>, |
|||
IPermissionDefinitionManager, |
|||
ITransientDependency |
|||
{ |
|||
protected IStaticPermissionDefinitionStore StaticStore { get; } |
|||
protected IDynamicPermissionDefinitionStore DynamicStore { get; } |
|||
public PermissionDynamicDefinitionManager( |
|||
IStaticPermissionDefinitionStore staticStore, |
|||
IDynamicPermissionDefinitionStore dynamicStore, |
|||
IOptions<AbpDynamicDefinitionsOptions> options) : base(options) |
|||
{ |
|||
StaticStore = staticStore; |
|||
DynamicStore = dynamicStore; |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition> GetAsync(string name) |
|||
{ |
|||
return await GetOrNullAsync(name) ?? throw new AbpException("Undefined permission: " + name); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroupDefinitions = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroupDefinitions = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
return await GetGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition?> GetOrNullAsync(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetOrNullAsync(name); |
|||
var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetPermissionsAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetPermissionsAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition> GetResourcePermissionAsync(string resourceName, string name) |
|||
{ |
|||
return await GetResourcePermissionOrNullAsync(resourceName, name) |
|||
?? throw new AbpException($"Undefined resource permission: {name} for resource: {resourceName}"); |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition?> GetResourcePermissionOrNullAsync(string resourceName, string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetResourcePermissionOrNullAsync(resourceName, name); |
|||
var dynamicDefinition = await DynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetResourcePermissionsAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
protected override string GetDefinitionKey(PermissionDefinition definition) |
|||
{ |
|||
return definition.Name; |
|||
} |
|||
|
|||
protected override string GetGroupDefinitionKey(PermissionGroupDefinition groupDefinition) |
|||
{ |
|||
return groupDefinition.Name; |
|||
} |
|||
|
|||
protected override Task<PermissionDefinition> MergeDefinitionAsync(PermissionDefinition targetDefinition, PermissionDefinition sourceDefinition) |
|||
{ |
|||
targetDefinition.DisplayName = sourceDefinition.DisplayName; |
|||
if (sourceDefinition.ResourceName != null) |
|||
{ |
|||
targetDefinition.ResourceName = sourceDefinition.ResourceName; |
|||
} |
|||
if (sourceDefinition.ManagementPermissionName != null) |
|||
{ |
|||
targetDefinition.ManagementPermissionName = sourceDefinition.ManagementPermissionName; |
|||
} |
|||
|
|||
if (sourceDefinition.MultiTenancySide != MultiTenancySides.Both) |
|||
{ |
|||
targetDefinition.MultiTenancySide |= sourceDefinition.MultiTenancySide; |
|||
} |
|||
|
|||
targetDefinition.IsEnabled = targetDefinition.IsEnabled || sourceDefinition.IsEnabled; |
|||
|
|||
CopyPermissionDetails(targetDefinition, sourceDefinition); |
|||
|
|||
return Task.FromResult(targetDefinition); |
|||
} |
|||
|
|||
protected async override Task MergeGroupDefinitionAsync(PermissionGroupDefinition targetGroupDefinition, PermissionGroupDefinition sourceGroupDefinition) |
|||
{ |
|||
if (sourceGroupDefinition.DisplayName != null) |
|||
{ |
|||
targetGroupDefinition.DisplayName = sourceGroupDefinition.DisplayName; |
|||
} |
|||
foreach (var property in sourceGroupDefinition.Properties) |
|||
{ |
|||
targetGroupDefinition.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var sourcePermission in sourceGroupDefinition.Permissions) |
|||
{ |
|||
var existingPermission = targetGroupDefinition.GetPermissionOrNull(sourcePermission.Name); |
|||
|
|||
if (existingPermission == null) |
|||
{ |
|||
var newPermission = targetGroupDefinition.AddPermission( |
|||
sourcePermission.Name, |
|||
sourcePermission.DisplayName, |
|||
sourcePermission.MultiTenancySide, |
|||
sourcePermission.IsEnabled |
|||
); |
|||
newPermission.ResourceName = sourcePermission.ResourceName; |
|||
newPermission.ManagementPermissionName = sourcePermission.ManagementPermissionName; |
|||
|
|||
CopyPermissionDetails(sourcePermission, newPermission); |
|||
|
|||
foreach (var child in sourcePermission.Children) |
|||
{ |
|||
AddChildPermissionRecursively(newPermission, child); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
await MergeDefinitionAsync(existingPermission, sourcePermission); |
|||
|
|||
foreach (var sourceChild in sourcePermission.Children) |
|||
{ |
|||
await MergeChildPermissions(existingPermission, sourceChild); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected async override Task AfterMergeDefinitionAsync(PermissionDefinition targetDefinition, PermissionDefinition sourceDefinition) |
|||
{ |
|||
foreach (var child in sourceDefinition.Children) |
|||
{ |
|||
await MergeChildPermissions(targetDefinition, child); |
|||
} |
|||
} |
|||
|
|||
private async Task MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) |
|||
{ |
|||
var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); |
|||
|
|||
if (existingChild == null) |
|||
{ |
|||
var newChild = parent.AddChild( |
|||
sourceChild.Name, |
|||
sourceChild.DisplayName, |
|||
sourceChild.MultiTenancySide, |
|||
sourceChild.IsEnabled |
|||
); |
|||
newChild.ResourceName = sourceChild.ResourceName; |
|||
newChild.ManagementPermissionName = sourceChild.ManagementPermissionName; |
|||
|
|||
CopyPermissionDetails(sourceChild, newChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
AddChildPermissionRecursively(newChild, grandchild); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
await MergeDefinitionAsync(existingChild, sourceChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
await MergeChildPermissions(existingChild, grandchild); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) |
|||
{ |
|||
var newChild = parent.AddChild( |
|||
sourceChild.Name, |
|||
sourceChild.DisplayName, |
|||
sourceChild.MultiTenancySide, |
|||
sourceChild.IsEnabled |
|||
); |
|||
newChild.ResourceName = sourceChild.ResourceName; |
|||
newChild.ManagementPermissionName = sourceChild.ManagementPermissionName; |
|||
|
|||
CopyPermissionDetails(sourceChild, newChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
AddChildPermissionRecursively(newChild, grandchild); |
|||
} |
|||
} |
|||
|
|||
private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) |
|||
{ |
|||
foreach (var property in source.Properties) |
|||
{ |
|||
target.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var provider in source.Providers) |
|||
{ |
|||
if (!target.Providers.Contains(provider)) |
|||
{ |
|||
target.Providers.Add(provider); |
|||
} |
|||
} |
|||
|
|||
foreach (var checker in source.StateCheckers) |
|||
{ |
|||
if (!target.StateCheckers.Contains(checker)) |
|||
{ |
|||
target.StateCheckers.Add(checker); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(ISettingDefinitionManager), |
|||
typeof(SettingDynamicDefinitionManager))] |
|||
public class SettingDynamicDefinitionManager : |
|||
DynamicDefinitionManager<SettingDefinition>, |
|||
ISettingDefinitionManager, |
|||
ISingletonDependency |
|||
{ |
|||
protected IStaticSettingDefinitionStore StaticStore { get; } |
|||
protected IDynamicSettingDefinitionStore DynamicStore { get; } |
|||
public SettingDynamicDefinitionManager( |
|||
IStaticSettingDefinitionStore staticStore, |
|||
IDynamicSettingDefinitionStore dynamicStore, |
|||
IOptions<AbpDynamicDefinitionsOptions> options) : base(options) |
|||
{ |
|||
StaticStore = staticStore; |
|||
DynamicStore = dynamicStore; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetAllAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetAllAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<SettingDefinition> GetAsync(string name) |
|||
{ |
|||
return await GetOrNullAsync(name) ?? throw new AbpException("Undefined setting: " + name); |
|||
} |
|||
|
|||
public async virtual Task<SettingDefinition?> GetOrNullAsync(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetOrNullAsync(name); |
|||
var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
protected override string GetDefinitionKey(SettingDefinition definition) |
|||
{ |
|||
return definition.Name; |
|||
} |
|||
|
|||
protected override Task<SettingDefinition> MergeDefinitionAsync(SettingDefinition targetDefinition, SettingDefinition sourceDefinition) |
|||
{ |
|||
targetDefinition.DisplayName = sourceDefinition.DisplayName; |
|||
targetDefinition.Description = sourceDefinition.Description ?? targetDefinition.Description; |
|||
targetDefinition.DefaultValue = sourceDefinition.DefaultValue ?? targetDefinition.DefaultValue; |
|||
targetDefinition.IsVisibleToClients = targetDefinition.IsVisibleToClients || sourceDefinition.IsVisibleToClients; |
|||
targetDefinition.IsInherited = targetDefinition.IsInherited || sourceDefinition.IsInherited; |
|||
targetDefinition.IsEncrypted = targetDefinition.IsEncrypted || sourceDefinition.IsEncrypted; |
|||
|
|||
foreach (var property in sourceDefinition.Properties) |
|||
{ |
|||
targetDefinition.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var provider in sourceDefinition.Providers) |
|||
{ |
|||
if (!targetDefinition.Providers.Contains(provider)) |
|||
{ |
|||
targetDefinition.Providers.Add(provider); |
|||
} |
|||
} |
|||
|
|||
return Task.FromResult(targetDefinition); |
|||
} |
|||
} |
|||
@ -0,0 +1,99 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(ITemplateDefinitionManager), |
|||
typeof(TemplateDynamicDefinitionManager))] |
|||
public class TemplateDynamicDefinitionManager : |
|||
DynamicDefinitionManager<TemplateDefinition>, |
|||
ITemplateDefinitionManager, |
|||
ISingletonDependency |
|||
{ |
|||
protected IStaticTemplateDefinitionStore StaticStore { get; } |
|||
protected IDynamicTemplateDefinitionStore DynamicStore { get; } |
|||
|
|||
public TemplateDynamicDefinitionManager( |
|||
IStaticTemplateDefinitionStore staticStore, |
|||
IDynamicTemplateDefinitionStore dynamicStore, |
|||
IOptions<AbpDynamicDefinitionsOptions> options) : base(options) |
|||
{ |
|||
StaticStore = staticStore; |
|||
DynamicStore = dynamicStore; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetAllAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetAllAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<TemplateDefinition> GetAsync(string name) |
|||
{ |
|||
return await GetOrNullAsync(name) ?? throw new AbpException("Undefined Template: " + name); |
|||
} |
|||
|
|||
public async virtual Task<TemplateDefinition?> GetOrNullAsync(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetOrNullAsync(name); |
|||
var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
protected override string GetDefinitionKey(TemplateDefinition definition) |
|||
{ |
|||
return definition.Name; |
|||
} |
|||
|
|||
protected override Task<TemplateDefinition> MergeDefinitionAsync(TemplateDefinition targetDefinition, TemplateDefinition sourceDefinition) |
|||
{ |
|||
var localizationResourceName = sourceDefinition.LocalizationResourceName ?? targetDefinition.LocalizationResourceName; |
|||
var defaultCultureName = sourceDefinition.DefaultCultureName ?? targetDefinition.DefaultCultureName; |
|||
var displayName = sourceDefinition.DisplayName ?? targetDefinition.DisplayName; |
|||
var isLayout = sourceDefinition.IsLayout || targetDefinition.IsLayout; |
|||
var layout = sourceDefinition.Layout ?? targetDefinition.Layout; |
|||
|
|||
var mergedTemplate = new TemplateDefinition( |
|||
targetDefinition.Name, |
|||
localizationResourceName, |
|||
displayName, |
|||
isLayout, |
|||
layout, |
|||
defaultCultureName |
|||
); |
|||
|
|||
foreach (var property in targetDefinition.Properties) |
|||
{ |
|||
mergedTemplate.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var property in sourceDefinition.Properties) |
|||
{ |
|||
mergedTemplate.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
if (!string.IsNullOrEmpty(sourceDefinition.RenderEngine)) |
|||
{ |
|||
mergedTemplate.RenderEngine = sourceDefinition.RenderEngine; |
|||
} |
|||
else if (!string.IsNullOrEmpty(targetDefinition.RenderEngine)) |
|||
{ |
|||
mergedTemplate.RenderEngine = targetDefinition.RenderEngine; |
|||
} |
|||
|
|||
mergedTemplate.IsInlineLocalized = sourceDefinition.IsInlineLocalized || targetDefinition.IsInlineLocalized; |
|||
|
|||
return Task.FromResult(mergedTemplate); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue