Browse Source

rules engine module

pull/101/head
cKey 5 years ago
parent
commit
a90e47393b
  1. 19
      aspnet-core/LINGYUN.MicroService.sln
  2. 31
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/AbpNRulesModule.cs
  3. 7
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN.Abp.Rules.NRules.csproj
  4. 14
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/AbpNRulesOptions.cs
  5. 44
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/AbpRuleRepository.cs
  6. 20
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/DependencyResolver.cs
  7. 20
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/INRulesRepository.cs
  8. 60
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/NRulesEntityRuleContributor.cs
  9. 24
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/RuleActivator.cs
  10. 55
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/Microsoft/Extensions/DependencyInjection/NRulesServiceCollectionExtensions.cs
  11. 15
      aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/NRules/RuleRepositoryExtensions.cs
  12. 28
      aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/Rule.cs
  13. 22
      aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleGroup.cs
  14. 35
      aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleNameAttribute.cs
  15. 6
      aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleParam.cs
  16. 22
      aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/AbpRulesEngineModule.cs
  17. 50
      aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsEntityRuleContributor.cs
  18. 27
      aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsRulesEngineMapperProfile.cs
  19. 7
      aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/README.md
  20. 8
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application.Contracts/Class1.cs
  21. 18
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application.Contracts/LINGYUN.Abp.RulesManagement.Application.Contracts.csproj
  22. 8
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application/Class1.cs
  23. 18
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application/LINGYUN.Abp.RulesManagement.Application.csproj
  24. 19
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN.Abp.RulesManagement.Domain.Shared.csproj
  25. 28
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/AbpRulesManagementDomainSharedModule.cs
  26. 11
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleConsts.cs
  27. 18
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleEto.cs
  28. 9
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleGroupConsts.cs
  29. 18
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleGroupEto.cs
  30. 8
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleParamConsts.cs
  31. 9
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/Localization/RulesResource.cs
  32. 20
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN.Abp.RulesManagement.Domain.csproj
  33. 31
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/AbpRulesManagementDomainModule.cs
  34. 163
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRule.cs
  35. 34
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleDataSeeder.cs
  36. 131
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleFinder.cs
  37. 103
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleGroup.cs
  38. 35
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleInGroup.cs
  39. 39
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleInject.cs
  40. 44
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleParam.cs
  41. 35
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntitySubRule.cs
  42. 9
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/IEntityRuleDataSeeder.cs
  43. 40
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/IEntityRuleGroupRepository.cs
  44. 35
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/IEntityRuleRepository.cs
  45. 13
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/RulesManagementDbProperties.cs
  46. 22
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/RulesManagementMapperProfile.cs
  47. 18
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN.Abp.RulesManagement.EntityFrameworkCore.csproj
  48. 21
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/AbpRulesManagementEntityFrameworkCoreModule.cs
  49. 98
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/EfCoreEntityRuleGroupRepository.cs
  50. 76
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/EfCoreEntityRuleRepository.cs
  51. 13
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/IRulesManagementDbContext.cs
  52. 25
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementDbContext.cs
  53. 81
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementDbContextModelBuilderExtensions.cs
  54. 32
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementEfCoreQueryableExtensions.cs
  55. 15
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementModelBuilderConfigurationOptions.cs
  56. 8
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi.Client/Class1.cs
  57. 18
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi.Client/LINGYUN.Abp.RulesManagement.HttpApi.Client.csproj
  58. 8
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi/Class1.cs
  59. 18
      aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi/LINGYUN.Abp.RulesManagement.HttpApi.csproj
  60. 9
      aspnet-core/modules/rules-management/README.md

19
aspnet-core/LINGYUN.MicroService.sln

@ -241,7 +241,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Auditing.HttpAp
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Rules", "modules\common\LINGYUN.Abp.Rules\LINGYUN.Abp.Rules.csproj", "{8ACB30CF-2311-4C0A-AE79-92C1A7667353}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Rules", "modules\common\LINGYUN.Abp.Rules\LINGYUN.Abp.Rules.csproj", "{8ACB30CF-2311-4C0A-AE79-92C1A7667353}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RulesEngine", "modules\common\LINGYUN.Abp.RulesEngine\LINGYUN.Abp.RulesEngine.csproj", "{FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Rules.NRules", "modules\common\LINGYUN.Abp.Rules.NRules\LINGYUN.Abp.Rules.NRules.csproj", "{0BA9FF71-C55E-483B-B83A-6B4BD8ABBBB1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.RulesEngine", "modules\common\LINGYUN.Abp.RulesEngine\LINGYUN.Abp.RulesEngine.csproj", "{E796CB81-8F94-40C4-87B3-FA9FBAD3F54E}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -641,10 +643,14 @@ Global
{8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Debug|Any CPU.Build.0 = Debug|Any CPU {8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Release|Any CPU.ActiveCfg = Release|Any CPU {8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Release|Any CPU.Build.0 = Release|Any CPU {8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Release|Any CPU.Build.0 = Release|Any CPU
{FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0BA9FF71-C55E-483B-B83A-6B4BD8ABBBB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Debug|Any CPU.Build.0 = Debug|Any CPU {0BA9FF71-C55E-483B-B83A-6B4BD8ABBBB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Release|Any CPU.ActiveCfg = Release|Any CPU {0BA9FF71-C55E-483B-B83A-6B4BD8ABBBB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Release|Any CPU.Build.0 = Release|Any CPU {0BA9FF71-C55E-483B-B83A-6B4BD8ABBBB1}.Release|Any CPU.Build.0 = Release|Any CPU
{E796CB81-8F94-40C4-87B3-FA9FBAD3F54E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E796CB81-8F94-40C4-87B3-FA9FBAD3F54E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E796CB81-8F94-40C4-87B3-FA9FBAD3F54E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E796CB81-8F94-40C4-87B3-FA9FBAD3F54E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -766,7 +772,8 @@ Global
{AC3C8985-73C2-472A-8E76-A0B8786FEC3F} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4} {AC3C8985-73C2-472A-8E76-A0B8786FEC3F} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4}
{07E19CA8-671D-4D58-9FED-5FEE9AE01A2F} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4} {07E19CA8-671D-4D58-9FED-5FEE9AE01A2F} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4}
{8ACB30CF-2311-4C0A-AE79-92C1A7667353} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {8ACB30CF-2311-4C0A-AE79-92C1A7667353} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {0BA9FF71-C55E-483B-B83A-6B4BD8ABBBB1} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{E796CB81-8F94-40C4-87B3-FA9FBAD3F54E} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

31
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/AbpNRulesModule.cs

@ -0,0 +1,31 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using Volo.Abp.Modularity;
using NRule = NRules.Fluent.Dsl.Rule;
namespace LINGYUN.Abp.Rules.NRules
{
[DependsOn(
typeof(AbpRulesModule)
)]
public class AbpNRulesModule : AbpModule
{
private readonly AbpNRulesOptions options = new AbpNRulesOptions();
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddObjectAccessor(options);
context.Services.OnRegistred(ctx =>
{
if (ctx.ImplementationType.IsAssignableTo(typeof(NRule)))
{
options.Rules.AddIfNotContains(ctx.ImplementationType);
}
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddNRules(options);
}
}
}

7
aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN.Abp.RulesEngine.csproj → aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN.Abp.Rules.NRules.csproj

@ -8,12 +8,15 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="RulesEngine" Version="2.1.2" /> <PackageReference Include="NRules" Version="0.9.0" />
<PackageReference Include="Volo.Abp.AutoMapper" Version="3.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Rules\LINGYUN.Abp.Rules.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.Rules\LINGYUN.Abp.Rules.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\Rules\NRules\" />
</ItemGroup>
</Project> </Project>

14
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/AbpNRulesOptions.cs

@ -0,0 +1,14 @@
using Volo.Abp.Collections;
using NRule = NRules.Fluent.Dsl.Rule;
namespace LINGYUN.Abp.Rules
{
public class AbpNRulesOptions
{
public ITypeList<NRule> Rules { get; }
public AbpNRulesOptions()
{
Rules = new TypeList<NRule>();
}
}
}

44
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/AbpRuleRepository.cs

@ -0,0 +1,44 @@
using NRules.RuleModel;
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.Rules
{
public class AbpRuleRepository : INRulesRepository
{
public void Add(IRuleSet ruleSet)
{
throw new NotImplementedException();
}
public IEnumerable<IRuleSet> GetRuleSets()
{
throw new NotImplementedException();
}
public void Remove(string ruleSetName)
{
throw new NotImplementedException();
}
public void Remove(IRuleSet ruleSet)
{
throw new NotImplementedException();
}
public IRuleSet GetRuleSet(string ruleSetName)
{
return new RuleSet(ruleSetName);
}
public IRuleSet GetRuleSet(RuleGroup group)
{
throw new NotImplementedException();
}
public IEnumerable<IRuleSet> GetRuleSets(IEnumerable<RuleGroup> groups)
{
throw new NotImplementedException();
}
}
}

20
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/DependencyResolver.cs

@ -0,0 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
using NRules.Extensibility;
using System;
namespace LINGYUN.Abp.Rules
{
public class DependencyResolver : IDependencyResolver
{
protected IServiceProvider ServiceProvider { get; }
public DependencyResolver(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public virtual object Resolve(IResolutionContext context, Type serviceType)
{
return ServiceProvider.GetRequiredService(serviceType);
}
}
}

20
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/INRulesRepository.cs

@ -0,0 +1,20 @@
using NRules.RuleModel;
using System.Collections.Generic;
namespace LINGYUN.Abp.Rules
{
public interface INRulesRepository : IRuleRepository
{
void Add(IRuleSet ruleSet);
void Remove(string ruleSetName);
void Remove(IRuleSet ruleSet);
IRuleSet GetRuleSet(string ruleSetName);
IRuleSet GetRuleSet(RuleGroup group);
IEnumerable<IRuleSet> GetRuleSets(IEnumerable<RuleGroup> groups);
}
}

60
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/NRulesEntityRuleContributor.cs

@ -0,0 +1,60 @@
using Microsoft.Extensions.DependencyInjection;
using NRules.RuleModel;
using NRules.RuleModel.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.Rules
{
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IEntityRuleContributor))]
public class NRulesEntityRuleContributor : IEntityRuleContributor
{
protected INRulesRepository Repository { get; }
public Task ApplyAsync(EntityRuleContext context)
{
var entityType = context.Entity.GetType();
var entityRuleName = RuleNameAttribute.GetRuleName(entityType);
IEnumerable<IRuleSet> groupRuleSets = new List<IRuleSet>();
groupRuleSets = Repository.GetRuleSets(context.Groups);
var sessionFactory = Repository.Compile(context.Groups);
var session = sessionFactory.CreateSession();
session.Insert(context.Entity);
session.Fire();
foreach (var groupRuleSet in groupRuleSets)
{
}
foreach (var group in context.Groups)
{
var groupRuleSet = new RuleSet(group.Name);
Repository.GetRuleSet(group.Name);
foreach (var rule in group.Rules)
{
var builder = new RuleBuilder();
builder.Name(rule.Name);
PatternBuilder thisRulePattern = builder.LeftHandSide().Pattern(entityType, entityRuleName);
ParameterExpression thisRuleParameter = thisRulePattern.Declaration.ToParameterExpression();
var ruleCondition = Expression.Lambda(DynamicExpressionParser.ParseLambda(typeof(bool), rule.Expression), thisRuleParameter);
thisRulePattern.Condition(ruleCondition);
}
}
throw new NotImplementedException();
}
}
}

24
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/LINGYUN/Abp/Rules/RuleActivator.cs

@ -0,0 +1,24 @@
using Microsoft.Extensions.DependencyInjection;
using NRules.Fluent;
using System;
using System.Collections.Generic;
using Volo.Abp.DependencyInjection;
using NRule = NRules.Fluent.Dsl.Rule;
namespace LINGYUN.Abp.Rules
{
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IRuleActivator))]
public class RuleActivator : IRuleActivator
{
protected IServiceProvider ServiceProvider { get; }
public RuleActivator(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public virtual IEnumerable<NRule> Activate(Type type)
{
return (IEnumerable<NRule>)ServiceProvider.GetServices(type);
}
}
}

55
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/Microsoft/Extensions/DependencyInjection/NRulesServiceCollectionExtensions.cs

@ -0,0 +1,55 @@
using LINGYUN.Abp.Rules;
using NRules;
using NRules.Fluent;
using NRules.RuleModel;
using System;
namespace Microsoft.Extensions.DependencyInjection
{
public static class NRulesServiceCollectionExtensions
{
public static IServiceCollection AddNRules(this IServiceCollection services, AbpNRulesOptions options)
{
services.RegisterRepository();
services.RegisterSessionFactory();
services.RegisterSession();
return services;
}
public static IServiceCollection RegisterRepository(this IServiceCollection services)
{
services.AddSingleton<IRuleActivator, RuleActivator>();
services.AddSingleton<IRuleRepository, AbpRuleRepository>();
services.AddSingleton<INRulesRepository, AbpRuleRepository>();
return services;
}
public static IServiceCollection RegisterSessionFactory(this IServiceCollection services)
{
services.RegisterSessionFactory((provider) => provider.GetRequiredService<IRuleRepository>().Compile());
return services;
}
public static IServiceCollection RegisterSessionFactory(this IServiceCollection services, Func<IServiceProvider, ISessionFactory> compileFunc)
{
services.AddSingleton<IRuleActivator, RuleActivator>();
services.AddSingleton(compileFunc);
return services;
}
public static IServiceCollection RegisterSession(this IServiceCollection services)
{
return services.RegisterSession((provider) => provider.GetRequiredService<ISessionFactory>().CreateSession());
}
public static IServiceCollection RegisterSession(this IServiceCollection services, Func<IServiceProvider, ISession> factoryFunc)
{
return services.AddScoped(factoryFunc);
}
}
}

15
aspnet-core/modules/common/LINGYUN.Abp.Rules.NRules/NRules/RuleRepositoryExtensions.cs

@ -0,0 +1,15 @@
using NRules;
using System.Collections.Generic;
namespace LINGYUN.Abp.Rules
{
public static class RuleRepositoryExtensions
{
public static ISessionFactory Compile(this INRulesRepository repository, IEnumerable<RuleGroup> groups)
{
var compiler = new RuleCompiler();
ISessionFactory factory = compiler.Compile(repository.GetRuleSets(groups));
return factory;
}
}
}

28
aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/Rule.cs

@ -11,21 +11,21 @@ namespace LINGYUN.Abp.Rules
public class Rule public class Rule
{ {
[NotNull] [NotNull]
public string Name { get; } public string Name { get; set; }
public string Operator { get; } public string Operator { get; set; }
public string ErrorMessage { get; } public string ErrorMessage { get; set; }
public DateTime CreationTime { get; } public DateTime CreationTime { get; set; }
public ErrorType ErrorType { get; } public ErrorType ErrorType { get; set; }
public ExpressionType? ExpressionType { get; } public ExpressionType? ExpressionType { get; set; }
public List<Rule> Rules { get; } public List<Rule> Rules { get; set; }
public List<string> InjectRules { get; } public List<string> InjectRules { get; set; }
public List<RuleParam> Params { get; } public List<RuleParam> Params { get; set; }
public string Expression { get; } public string Expression { get; set; }
public string SuccessEvent { get; } public string SuccessEvent { get; set; }
protected Rule() { }
public Rule( public Rule(
[NotNull] string name, [NotNull] string name,
string @operator, string operation,
DateTime creationTime, DateTime creationTime,
string expression = null, string expression = null,
string successEvent = null, string successEvent = null,
@ -35,7 +35,7 @@ namespace LINGYUN.Abp.Rules
Check.NotNullOrWhiteSpace(name, nameof(name)); Check.NotNullOrWhiteSpace(name, nameof(name));
Name = name; Name = name;
Operator = @operator; Operator = operation;
CreationTime = creationTime; CreationTime = creationTime;
Expression = expression; Expression = expression;
SuccessEvent = successEvent; SuccessEvent = successEvent;

22
aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleGroup.cs

@ -7,10 +7,10 @@ namespace LINGYUN.Abp.Rules
public class RuleGroup public class RuleGroup
{ {
[NotNull] [NotNull]
public string Name { get; } public string Name { get; set; }
public List<string> InjectRules { get; } public List<string> InjectRules { get; set; }
public List<Rule> Rules { get; } public List<Rule> Rules { get; }
protected RuleGroup() { }
public RuleGroup( public RuleGroup(
[NotNull] string name) [NotNull] string name)
{ {
@ -22,18 +22,32 @@ namespace LINGYUN.Abp.Rules
InjectRules = new List<string>(); InjectRules = new List<string>();
} }
public RuleGroup InjectRule(string ruleName) public RuleGroup WithInjectRule(string ruleName)
{ {
InjectRules.AddIfNotContains(ruleName); InjectRules.AddIfNotContains(ruleName);
return this; return this;
} }
public RuleGroup WithInjectRule(IEnumerable<string> ruleNames)
{
InjectRules.AddIfNotContains(ruleNames);
return this;
}
public RuleGroup WithRule(Rule rule) public RuleGroup WithRule(Rule rule)
{ {
Rules.AddIfNotContains(rule); Rules.AddIfNotContains(rule);
return this; return this;
} }
public RuleGroup WithRule(IEnumerable<Rule> rules)
{
Rules.AddIfNotContains(rules);
return this;
}
} }
} }

35
aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleNameAttribute.cs

@ -0,0 +1,35 @@
using System;
using System.Reflection;
namespace LINGYUN.Abp.Rules
{
public class RuleNameAttribute : Attribute
{
public string Name { get; }
public RuleNameAttribute(string name)
{
Name = name;
}
public virtual string GetRuleNameForType(Type ruleType)
{
return Name;
}
public static string GetRuleName<TEntity>()
{
return GetRuleName(typeof(TEntity));
}
public static string GetRuleName(Type entityType)
{
var ruleAttribute = entityType.GetSingleAttributeOrNull<RuleNameAttribute>();
if (ruleAttribute != null)
{
return ruleAttribute.GetRuleNameForType(entityType);
}
return entityType.Name.RemovePostFix("Rule").ToKebabCase();
}
}
}

6
aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleParam.cs

@ -6,10 +6,12 @@ namespace LINGYUN.Abp.Rules
public class RuleParam public class RuleParam
{ {
[NotNull] [NotNull]
public string Name { get; } public string Name { get; set; }
[NotNull] [NotNull]
public string Expression { get; } public string Expression { get; set; }
protected RuleParam() { }
public RuleParam( public RuleParam(
[NotNull] string name, [NotNull] string name,
[NotNull] string expression) [NotNull] string expression)

22
aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/AbpRulesEngineModule.cs

@ -1,22 +0,0 @@
using LINGYUN.Abp.Rules;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.RulesEngine
{
[DependsOn(
typeof(AbpRulesModule),
typeof(AbpAutoMapperModule))]
public class AbpRulesEngineModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpRulesEngineModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<MsRulesEngineMapperProfile>(validate: true);
});
}
}
}

50
aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsEntityRuleContributor.cs

@ -1,50 +0,0 @@
using LINGYUN.Abp.Rules;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RulesEngine.Extensions;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ObjectMapping;
using MsRulesEngine = RulesEngine.RulesEngine;
using MsWorkflowRules = RulesEngine.Models.WorkflowRules;
namespace LINGYUN.Abp.RulesEngine
{
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IEntityRuleContributor))]
public class MsEntityRuleContributor : IEntityRuleContributor
{
protected ILogger Logger { get; }
protected IObjectMapper ObjectMapper { get; }
public MsEntityRuleContributor(
IObjectMapper objectMapper,
ILogger<MsEntityRuleContributor> logger)
{
Logger = logger;
ObjectMapper = objectMapper;
}
public Task ApplyAsync(EntityRuleContext context)
{
var workflowRules = ObjectMapper.Map<List<RuleGroup>, List<MsWorkflowRules>>(context.Groups);
var rulesEngine = new MsRulesEngine(workflowRules.ToArray(), Logger);
foreach(var workflow in workflowRules)
{
var ruleRsults = rulesEngine.ExecuteRule(workflow.WorkflowName, context.Entity);
ruleRsults.OnSuccess((eventName) =>
{
Logger.LogDebug($"{workflow.WorkflowName} evaluation resulted in succees - {eventName}");
});
ruleRsults.OnFail(() =>
{
Logger.LogWarning($"{workflow.WorkflowName} evaluation resulted in failure");
});
}
return Task.CompletedTask;
}
}
}

27
aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsRulesEngineMapperProfile.cs

@ -1,27 +0,0 @@
using AutoMapper;
using LINGYUN.Abp.Rules;
using MsExpressionType = RulesEngine.Models.RuleExpressionType;
using MsRule = RulesEngine.Models.Rule;
using MsRuleErrorType = RulesEngine.Models.ErrorType;
using MsRuleParam = RulesEngine.Models.LocalParam;
using MsWorkflowRules = RulesEngine.Models.WorkflowRules;
namespace LINGYUN.Abp.RulesEngine
{
public class MsRulesEngineMapperProfile : Profile
{
public MsRulesEngineMapperProfile()
{
CreateMap<RuleParam, MsRuleParam>();
CreateMap<Rule, MsRule>()
.ForMember(r => r.LocalParams, map => map.MapFrom(m => m.Params))
.ForMember(r => r.WorkflowRulesToInject, map => map.MapFrom(m => m.InjectRules))
.ForMember(r => r.ErrorType, map => map.MapFrom(m => (MsRuleErrorType)m.ErrorType.GetHashCode()))
.ForMember(r => r.RuleExpressionType, map => map.MapFrom(m => (MsExpressionType)m.ExpressionType.GetHashCode()));
CreateMap<RuleGroup, MsWorkflowRules>()
.ForMember(wr => wr.WorkflowName, map => map.MapFrom(m => m.Name))
.ForMember(wr => wr.Rules, map => map.MapFrom(m => m.Rules))
.ForMember(wr => wr.WorkflowRulesToInject, map => map.MapFrom(m => m.InjectRules));
}
}
}

7
aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/README.md

@ -1,7 +0,0 @@
# LINGYUN.Abp.RulesEngine
规则引擎 [microsoft/RulesEngine](https://github.com/microsoft/RulesEngine) (RulesEngine) 实现
## 配置使用
待完善

8
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application.Contracts/Class1.cs

@ -0,0 +1,8 @@
using System;
namespace LINGYUN.Abp.RulesManagement
{
public class Class1
{
}
}

18
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application.Contracts/LINGYUN.Abp.RulesManagement.Application.Contracts.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\RulesManagement\" />
</ItemGroup>
</Project>

8
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application/Class1.cs

@ -0,0 +1,8 @@
using System;
namespace LINGYUN.Abp.RulesManagement.Application
{
public class Class1
{
}
}

18
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Application/LINGYUN.Abp.RulesManagement.Application.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\RulesManagement\" />
</ItemGroup>
</Project>

19
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN.Abp.RulesManagement.Domain.Shared.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Auditing" Version="3.2.0" />
<PackageReference Include="Volo.Abp.Validation" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\RulesManagement\Localization\Resources\" />
</ItemGroup>
</Project>

28
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/AbpRulesManagementDomainSharedModule.cs

@ -0,0 +1,28 @@
using LINGYUN.Abp.RulesManagement.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Validation;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.RulesManagement
{
[DependsOn(
typeof(AbpValidationModule))]
public class AbpRulesManagementDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpRulesManagementDomainSharedModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<RulesResource>()
.AddVirtualJson("/LINGYUN/Abp/RulesManagement/Localization/Resources");
});
}
}
}

11
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleConsts.cs

@ -0,0 +1,11 @@
namespace LINGYUN.Abp.RulesManagement
{
public static class EntityRuleConsts
{
public static int MaxNameLength { get; set; } = 64;
public static int MaxDisplayNameLength { get; set; } = 256;
public static int MaxOperatorLength { get; set; } = 64;
public static int MaxErrorMessageLength { get; set; } = 256;
public static int MaxExpressionLength { get; set; } = 1024;
}
}

18
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleEto.cs

@ -0,0 +1,18 @@
using System;
using Volo.Abp.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRuleEto : IMultiTenant, ICreationAuditedObject, IModificationAuditedObject
{
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public Guid? LastModifierId { get; set; }
public DateTime? LastModificationTime { get; set; }
public DateTime CreationTime { get; set; }
public Guid? CreatorId { get; set; }
}
}

9
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleGroupConsts.cs

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.RulesManagement
{
public static class EntityRuleGroupConsts
{
public static int MaxNameLength { get; set; } = 64;
public static int MaxDisplayNameLength { get; set; } = 256;
public static int MaxEntiyFullTypeNameLength { get; set; } = 256;
}
}

18
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleGroupEto.cs

@ -0,0 +1,18 @@
using System;
using Volo.Abp.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRuleGroupEto : IMultiTenant, ICreationAuditedObject, IModificationAuditedObject
{
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public Guid? LastModifierId { get; set; }
public DateTime? LastModificationTime { get; set; }
public DateTime CreationTime { get; set; }
public Guid? CreatorId { get; set; }
}
}

8
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/EntityRuleParamConsts.cs

@ -0,0 +1,8 @@
namespace LINGYUN.Abp.RulesManagement
{
public static class EntityRuleParamConsts
{
public static int MaxNameLength { get; set; } = 64;
public static int MaxExpressionLength { get; set; } = 1024;
}
}

9
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain.Shared/LINGYUN/Abp/RulesManagement/Localization/RulesResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.RulesManagement.Localization
{
[LocalizationResourceName("AbpRulesManagement")]
public class RulesResource
{
}
}

20
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN.Abp.RulesManagement.Domain.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="3.2.0" />
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\LINGYUN.Abp.Rules\LINGYUN.Abp.Rules.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.RulesManagement.Domain.Shared\LINGYUN.Abp.RulesManagement.Domain.Shared.csproj" />
</ItemGroup>
</Project>

31
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/AbpRulesManagementDomainModule.cs

@ -0,0 +1,31 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.RulesManagement
{
[DependsOn(
typeof(AbpDddDomainModule),
typeof(AbpAutoMapperModule),
typeof(AbpRulesManagementDomainSharedModule))]
public class AbpRulesManagementDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpRulesManagementDomainModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<RulesManagementMapperProfile>(validate: true);
});
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<EntityRule, EntityRuleEto>(typeof(AbpRulesManagementDomainModule));
options.EtoMappings.Add<EntityRuleInGroup, EntityRuleGroupEto>(typeof(AbpRulesManagementDomainModule));
});
}
}
}

163
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRule.cs

@ -0,0 +1,163 @@
using JetBrains.Annotations;
using LINGYUN.Abp.Rules;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRule : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 规则名称
/// </summary>
public virtual string Name { get; protected set; }
/// <summary>
/// 显示名称
/// </summary>
public virtual string DisplayName { get; protected set; }
/// <summary>
/// 操作类型
/// </summary>
public virtual string Operator { get; protected set; }
/// <summary>
/// 错误提示
/// </summary>
public virtual string ErrorMessage { get; protected set; }
/// <summary>
/// 错误类型
/// </summary>
public virtual ErrorType ErrorType { get; protected set; }
/// <summary>
/// 表达式类型
/// </summary>
public virtual ExpressionType? ExpressionType { get; set; }
/// <summary>
/// 所属规则
/// </summary>
public virtual Guid? ParentId { get; protected set; }
public virtual ICollection<EntitySubRule> SubRules { get; protected set; }
public virtual ICollection<EntityRuleInject> InjectRules { get; protected set; }
public virtual ICollection<EntityRuleParam> Params { get; protected set; }
public virtual string Expression { get; protected set; }
protected EntityRule()
{
}
public EntityRule(
[NotNull] Guid id,
[NotNull] string name,
[CanBeNull] string operation,
[CanBeNull] string displayName,
[CanBeNull] Guid? parentId = null,
[CanBeNull] Guid? tenantId = null)
{
Check.NotNull(id, nameof(id));
Check.NotNullOrWhiteSpace(name, nameof(name), EntityRuleConsts.MaxNameLength);
Id = id;
Name = name;
Operator = operation;
DisplayName = displayName;
ParentId = parentId;
TenantId = tenantId;
ExpressionType = Abp.Rules.ExpressionType.LambdaExpression;
Params = new Collection<EntityRuleParam>();
SubRules = new Collection<EntitySubRule>();
InjectRules = new Collection<EntityRuleInject>();
ExtraProperties = new Dictionary<string, object>();
}
public virtual void SetErrorInfomation(string errorMessage, ErrorType errorType = ErrorType.Warning)
{
ErrorType = errorType;
ErrorMessage = errorMessage;
}
public virtual void AddParamter([NotNull] IGuidGenerator guidGenerator, [NotNull] string name, [NotNull] string expression)
{
Check.NotNull(guidGenerator, nameof(guidGenerator));
if (Params.Any(p => p.Name == name))
{
return;
}
Params.Add(new EntityRuleParam(guidGenerator.Create(), Id, name, expression, TenantId));
}
public virtual void RemoveParamter([NotNull] string name)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
Params.RemoveAll(p => p.Name == name);
}
public virtual void AddInjectRule([NotNull] EntityRule rule)
{
Check.NotNull(rule, nameof(rule));
if (IsInjectRule(rule.Id))
{
return;
}
InjectRules.Add(new EntityRuleInject(rule.Id, Id, TenantId));
}
public virtual void RemoveInjectRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
if (IsInjectRule(ruleId))
{
return;
}
InjectRules.RemoveAll(rule => rule.RuleId == ruleId);
}
public virtual bool IsInjectRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
return InjectRules.Any(rule => rule.RuleId == ruleId);
}
public virtual void AddSubRule([NotNull] EntityRule rule)
{
Check.NotNull(rule, nameof(rule));
if (IsInRule(rule.Id))
{
return;
}
SubRules.Add(new EntitySubRule(Id, rule.Id, TenantId));
}
public virtual void RemoveSubRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
if (!IsInRule(ruleId))
{
return;
}
SubRules.RemoveAll(r => r.SubId == ruleId);
}
public virtual bool IsInRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
return SubRules.Any(r => r.SubId == ruleId);
}
}
}

34
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleDataSeeder.cs

@ -0,0 +1,34 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRuleDataSeeder : IEntityRuleDataSeeder, ITransientDependency
{
protected IGuidGenerator GuidGenerator { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IEntityRuleGroupRepository Repository { get; }
public EntityRuleDataSeeder(
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant,
IEntityRuleGroupRepository repository)
{
GuidGenerator = guidGenerator;
CurrentTenant = currentTenant;
Repository = repository;
}
public virtual async Task SeedAsync(EntityRuleInGroup group)
{
var findGroup = await Repository.GetByNameAsync(group.Name);
if (findGroup != null)
{
return;
}
await Repository.InsertAsync(group);
}
}
}

131
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleFinder.cs

@ -0,0 +1,131 @@
using LINGYUN.Abp.Rules;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Services;
using Volo.Abp.ObjectMapping;
namespace LINGYUN.Abp.RulesManagement
{
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IRuleFinder))]
public class EntityRuleFinder : DomainService, IRuleFinder
{
private IObjectMapper _objectMapper;
protected IObjectMapper ObjectMapper => LazyGetRequiredService(ref _objectMapper);
private IEntityRuleGroupRepository _ruleGroupRepository;
protected IEntityRuleGroupRepository RuleGroupRepository => LazyGetRequiredService(ref _ruleGroupRepository);
private IEntityRuleRepository _rruleRepository;
protected IEntityRuleRepository RuleRepository => LazyGetRequiredService(ref _rruleRepository);
public virtual async Task<List<RuleGroup>> GetRuleGroupsAsync(Type entityType)
{
var entityFullTypeName = entityType.FullName;
if (entityType.IsGenericType)
{
entityFullTypeName = entityType.GetGenericTypeDefinition().FullName;
}
else if (entityType.IsArray)
{
entityFullTypeName = entityType.GetElementType().FullName;
}
var entityRuleGroups = await RuleGroupRepository.GetListByTypeAsync(entityFullTypeName, includeDetails: true);
var ruleGroups = ObjectMapper.Map<List<EntityRuleGroup>, List<RuleGroup>>(entityRuleGroups);
foreach(var group in ruleGroups)
{
var entityRuleGroup = entityRuleGroups.Find(g => g.Name.Equals(group.Name));
if (entityRuleGroup != null)
{
foreach(var ruleInGroup in entityRuleGroup.Rules)
{
await AddRuleAsync(group, ruleInGroup.RuleId);
}
foreach(var ruleInject in entityRuleGroup.InjectRules)
{
await AddToInjectRuleAsync(group, ruleInject.RuleId);
}
}
}
return ruleGroups;
}
protected virtual async Task AddRuleAsync(RuleGroup ruleGroup, Guid ruleId)
{
var entityRule = await RuleRepository.FindAsync(ruleId);
if (entityRule == null)
{
return;
}
var rule = ObjectMapper.Map<EntityRule, Rule>(entityRule);
ruleGroup.WithRule(rule);
foreach (var subEntityRule in entityRule.SubRules)
{
await AddSubRuleAsync(rule, subEntityRule.SubId);
}
foreach (var ruleInject in entityRule.InjectRules)
{
// 如果依赖于某个规则,需要把此规则添加到集合
await AddRuleAsync(ruleGroup, ruleInject.InjectId);
// 添加依赖规则
await AddToInjectRuleAsync(ruleGroup, ruleInject.InjectId);
}
}
protected virtual async Task AddSubRuleAsync(Rule rule, Guid subRuleId)
{
var entityRule = await RuleRepository.FindAsync(subRuleId);
if (entityRule == null)
{
return;
}
var subRule = ObjectMapper.Map<EntityRule, Rule>(entityRule);
rule.CreateChildren(subRule);
foreach (var subEntityRule in entityRule.SubRules)
{
await AddSubRuleAsync(subRule, subEntityRule.SubId);
}
}
protected virtual async Task AddToInjectRuleAsync(RuleGroup group, Guid ruleId)
{
var entityRule = await RuleRepository.FindAsync(ruleId);
if (entityRule == null)
{
return;
}
group.WithInjectRule(entityRule.Name);
foreach (var injectRule in entityRule.InjectRules)
{
await AddToInjectRuleAsync(group, injectRule.InjectId);
}
}
protected virtual async Task AddToInjectRuleAsync(Rule rule, Guid ruleId)
{
var entityRule = await RuleRepository.FindAsync(ruleId);
if (entityRule == null)
{
return;
}
var injectRule = ObjectMapper.Map<EntityRule, Rule>(entityRule);
rule.CreateChildren(injectRule);
rule.InjectRule(entityRule.Name);
foreach (var injectSubRule in entityRule.InjectRules)
{
await AddToInjectRuleAsync(injectRule, injectSubRule.InjectId);
}
}
}
}

103
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleGroup.cs

@ -0,0 +1,103 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRuleGroup : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string Name { get; protected set; }
public virtual string DisplayName { get; protected set; }
public virtual string EntityFullTypeName { get; protected set; }
public virtual ICollection<EntityRuleInGroup> Rules { get; protected set; }
public virtual ICollection<EntityRuleInject> InjectRules { get; protected set; }
protected EntityRuleGroup()
{
}
public EntityRuleGroup(
[NotNull] Guid id,
[NotNull] string name,
[NotNull] string entiyFullTypeName,
[CanBeNull] string displayName,
[CanBeNull] Guid? tenantId = null)
{
Check.NotNull(id, nameof(id));
Check.NotNullOrWhiteSpace(name, nameof(name), EntityRuleGroupConsts.MaxNameLength);
Check.NotNullOrWhiteSpace(entiyFullTypeName, nameof(entiyFullTypeName), EntityRuleGroupConsts.MaxEntiyFullTypeNameLength);
Id = id;
Name = name;
DisplayName = displayName;
TenantId = tenantId;
Rules = new Collection<EntityRuleInGroup>();
InjectRules = new Collection<EntityRuleInject>();
ExtraProperties = new Dictionary<string, object>();
}
public virtual void AddInjectRule([NotNull] EntityRule rule)
{
Check.NotNull(rule, nameof(rule));
if (IsInjectRule(rule.Id))
{
return;
}
InjectRules.Add(new EntityRuleInject(rule.Id, Id, TenantId));
}
public virtual void RemoveInjectRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
if (IsInjectRule(ruleId))
{
return;
}
InjectRules.RemoveAll(rule => rule.RuleId == ruleId);
}
public virtual bool IsInjectRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
return InjectRules.Any(rule => rule.RuleId == ruleId);
}
public virtual void AddRule([NotNull] EntityRule rule)
{
Check.NotNull(rule, nameof(rule));
if (IsInRule(rule.Id))
{
return;
}
Rules.Add(new EntityRuleInGroup(rule.Id, Id, TenantId));
}
public virtual void RemoveRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
if (!IsInRule(ruleId))
{
return;
}
Rules.RemoveAll(r => r.RuleId == ruleId);
}
public virtual bool IsInRule([NotNull] Guid ruleId)
{
Check.NotNull(ruleId, nameof(ruleId));
return Rules.Any(r => r.RuleId == ruleId);
}
}
}

35
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleInGroup.cs

@ -0,0 +1,35 @@
using JetBrains.Annotations;
using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRuleInGroup : Entity, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid RuleId { get; protected set; }
public virtual Guid GroupId { get; protected set; }
protected EntityRuleInGroup()
{
}
public EntityRuleInGroup(
[NotNull] Guid ruleId,
[NotNull] Guid groupId,
[CanBeNull] Guid? tenantId = null)
{
Check.NotNull(ruleId, nameof(ruleId));
Check.NotNull(groupId, nameof(groupId));
RuleId = ruleId;
GroupId = groupId;
TenantId = tenantId;
}
public override object[] GetKeys()
{
return new object[] { RuleId, GroupId };
}
}
}

39
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleInject.cs

@ -0,0 +1,39 @@
using JetBrains.Annotations;
using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRuleInject : Entity, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 规则标识
/// </summary>
public virtual Guid RuleId { get; protected set; }
/// <summary>
/// 依赖的规则标识
/// </summary>
public virtual Guid InjectId { get; protected set; }
protected EntityRuleInject() { }
public EntityRuleInject(
[NotNull] Guid ruleId,
[NotNull] Guid injectId,
[CanBeNull] Guid? tenantId = null)
{
Check.NotNull(ruleId, nameof(ruleId));
Check.NotNull(injectId, nameof(injectId));
RuleId = ruleId;
InjectId = injectId;
TenantId = tenantId;
}
public override object[] GetKeys()
{
return new object[] { RuleId , InjectId };
}
}
}

44
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntityRuleParam.cs

@ -0,0 +1,44 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntityRuleParam : Entity<Guid>, IMultiTenant, IHasExtraProperties
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid RuleId { get; protected set; }
public virtual string Name { get; protected set; }
public virtual string Expression { get; protected set; }
public virtual Dictionary<string, object> ExtraProperties { get; protected set; }
protected EntityRuleParam()
{
}
public EntityRuleParam(
[NotNull] Guid id,
[NotNull] Guid ruleId,
[NotNull] string name,
[NotNull] string expression,
[CanBeNull] Guid? tenantId = null)
{
Check.NotNull(id, nameof(id));
Check.NotNull(ruleId, nameof(ruleId));
Check.NotNullOrWhiteSpace(name, nameof(name), EntityRuleParamConsts.MaxNameLength);
Check.NotNullOrWhiteSpace(expression, nameof(expression), EntityRuleParamConsts.MaxExpressionLength);
Id = id;
RuleId = ruleId;
Name = name;
Expression = expression;
TenantId = tenantId;
ExtraProperties = new Dictionary<string, object>();
}
}
}

35
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/EntitySubRule.cs

@ -0,0 +1,35 @@
using JetBrains.Annotations;
using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.RulesManagement
{
public class EntitySubRule : Entity, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid RuleId { get; protected set; }
public virtual Guid SubId { get; protected set; }
protected EntitySubRule()
{
}
public EntitySubRule(
[NotNull] Guid ruleId,
[NotNull] Guid subId,
[CanBeNull] Guid? tenantId = null)
{
Check.NotNull(ruleId, nameof(ruleId));
Check.NotNull(subId, nameof(subId));
RuleId = ruleId;
SubId = subId;
TenantId = tenantId;
}
public override object[] GetKeys()
{
return new object[] { RuleId, SubId };
}
}
}

9
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/IEntityRuleDataSeeder.cs

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.RulesManagement
{
public interface IEntityRuleDataSeeder
{
Task SeedAsync(EntityRuleInGroup group);
}
}

40
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/IEntityRuleGroupRepository.cs

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Abp.RulesManagement
{
public interface IEntityRuleGroupRepository : IBasicRepository<EntityRuleGroup, Guid>
{
Task<EntityRuleGroup> GetByNameAsync(
string name,
bool includeDetails = false,
CancellationToken cancellationToken = default
);
Task<List<EntityRuleGroup>> GetListByTypeAsync(
string entityFullTypeName,
string sorting = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<List<EntityRule>> GetRulesAsync(
Guid groupId,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default);
Task<List<EntityRuleGroup>> GetListAsync(
string filter = null,
string sorting = null,
int skipCount = 1,
int maxResultCount = 10,
bool includeDetails = false,
CancellationToken cancellationToken = default);
}
}

35
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/IEntityRuleRepository.cs

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Abp.RulesManagement
{
public interface IEntityRuleRepository : IBasicRepository<EntityRule, Guid>
{
Task<List<string>> GetInjectRuleNamesAsync(
Guid ruleId,
bool includeDetails = false,
CancellationToken cancellationToken = default
);
Task<List<EntityRule>> GetInjectRulesAsync(
Guid ruleId,
bool includeDetails = false,
CancellationToken cancellationToken = default
);
Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default);
Task<List<EntityRule>> GetListAsync(
string filter = null,
string sorting = null,
int skipCount = 1,
int maxResultCount = 10,
bool includeDetails = false,
CancellationToken cancellationToken = default);
}
}

13
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/RulesManagementDbProperties.cs

@ -0,0 +1,13 @@
using Volo.Abp.Data;
namespace LINGYUN.Abp.RulesManagement
{
public static class RulesManagementDbProperties
{
public static string DbTablePrefix { get; set; } = "App";
public static string DbSchema { get; set; } = AbpCommonDbProperties.DbSchema;
public const string ConnectionStringName = "AppRulesManagement";
}
}

22
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.Domain/LINGYUN/Abp/RulesManagement/RulesManagementMapperProfile.cs

@ -0,0 +1,22 @@
using AutoMapper;
using LINGYUN.Abp.Rules;
namespace LINGYUN.Abp.RulesManagement
{
public class RulesManagementMapperProfile : Profile
{
public RulesManagementMapperProfile()
{
CreateMap<EntityRuleParam, RuleParam>();
CreateMap<EntityRule, Rule>()
.ForMember(rule => rule.InjectRules, map => map.Ignore())
.ForMember(rule => rule.Rules, map => map.Ignore());
CreateMap<EntityRuleGroup, RuleGroup>()
.ForMember(rule => rule.InjectRules, map => map.Ignore())
.ForMember(rule => rule.Rules, map => map.Ignore());
CreateMap<EntityRule, EntityRuleEto>();
CreateMap<EntityRuleGroup, EntityRuleGroupEto>();
}
}
}

18
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN.Abp.RulesManagement.EntityFrameworkCore.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\RulesManagement\" />
</ItemGroup>
</Project>

21
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/AbpRulesManagementEntityFrameworkCoreModule.cs

@ -0,0 +1,21 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
[DependsOn(
typeof(AbpRulesManagementDomainModule),
typeof(AbpEntityFrameworkCoreModule))]
public class AbpRulesManagementEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<RulesManagementDbContext>(options =>
{
options.AddRepository<EntityRule, EfCoreEntityRuleRepository>();
options.AddRepository<EntityRuleInGroup, EfCoreEntityRuleGroupRepository>();
});
}
}
}

98
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/EfCoreEntityRuleGroupRepository.cs

@ -0,0 +1,98 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
public class EfCoreEntityRuleGroupRepository : EfCoreRepository<IRulesManagementDbContext, EntityRuleGroup, Guid>, IEntityRuleGroupRepository
{
public EfCoreEntityRuleGroupRepository(
IDbContextProvider<IRulesManagementDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<EntityRuleGroup> GetByNameAsync(
string name,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await this
.Where(ug => ug.Name.Equals(name))
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<EntityRule>> GetRulesAsync(
Guid groupId,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = from ruleGroup in DbContext.Set<EntityRuleInGroup>()
join rule in DbContext.EntityRules.IncludeDetails(includeDetails) on ruleGroup.RuleId equals rule.Id
where ruleGroup.GroupId == groupId
select rule;
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default)
{
return await this.WhereIf(
!filter.IsNullOrWhiteSpace(),
rg =>
rg.Name.Contains(filter) ||
rg.DisplayName.Contains(filter) ||
rg.EntityFullTypeName.Contains(filter)
)
.LongCountAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<EntityRuleGroup>> GetListByTypeAsync(
string entityFullTypeName,
string sorting = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
.IncludeDetails(includeDetails)
.Where(ug => ug.EntityFullTypeName.Equals(entityFullTypeName))
.OrderBy(sorting ?? nameof(EntityRuleGroup.CreationTime))
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<EntityRuleGroup>> GetListAsync(
string filter = null,
string sorting = null,
int skipCount = 1,
int maxResultCount = 10,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
.IncludeDetails(includeDetails)
.WhereIf(
!filter.IsNullOrWhiteSpace(),
rg =>
rg.Name.Contains(filter) ||
rg.DisplayName.Contains(filter) ||
rg.EntityFullTypeName.Contains(filter)
)
.OrderBy(sorting ?? nameof(EntityRuleGroup.CreationTime))
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public override IQueryable<EntityRuleGroup> WithDetails()
{
return GetQueryable().IncludeDetails();
}
}
}

76
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/EfCoreEntityRuleRepository.cs

@ -0,0 +1,76 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
public class EfCoreEntityRuleRepository : EfCoreRepository<IRulesManagementDbContext, EntityRule, Guid>, IEntityRuleRepository
{
public EfCoreEntityRuleRepository(
IDbContextProvider<IRulesManagementDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<List<EntityRule>> GetInjectRulesAsync(
Guid ruleId,
bool includeDetails = false,
CancellationToken cancellationToken = default
)
{
var query = from injectRule in DbContext.Set<EntityRuleInject>()
join rule in DbContext.EntityRules.IncludeDetails(includeDetails) on injectRule.InjectId equals rule.Id
where injectRule.RuleId == ruleId
select rule;
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default)
{
return await this
.WhereIf(
!filter.IsNullOrWhiteSpace(),
rg =>
rg.Name.Contains(filter) ||
rg.DisplayName.Contains(filter) ||
rg.Operator.Contains(filter)
)
.LongCountAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<EntityRule>> GetListAsync(
string filter = null,
string sorting = null,
int skipCount = 1,
int maxResultCount = 10,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await this
.WhereIf(
!filter.IsNullOrWhiteSpace(),
rg =>
rg.Name.Contains(filter) ||
rg.DisplayName.Contains(filter) ||
rg.Operator.Contains(filter)
)
.OrderBy(sorting ?? nameof(EntityRule.CreationTime))
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public override IQueryable<EntityRule> WithDetails()
{
return GetQueryable().IncludeDetails();
}
}
}

13
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/IRulesManagementDbContext.cs

@ -0,0 +1,13 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
[ConnectionStringName(RulesManagementDbProperties.ConnectionStringName)]
public interface IRulesManagementDbContext : IEfCoreDbContext
{
DbSet<EntityRule> EntityRules { get; set; }
DbSet<EntityRuleGroup> EntityRuleGroups { get; set; }
}
}

25
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementDbContext.cs

@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
[ConnectionStringName(RulesManagementDbProperties.ConnectionStringName)]
public class RulesManagementDbContext : AbpDbContext<RulesManagementDbContext>, IRulesManagementDbContext
{
public DbSet<EntityRule> EntityRules { get; set; }
public DbSet<EntityRuleGroup> EntityRuleGroups { get; set; }
public RulesManagementDbContext(
DbContextOptions<RulesManagementDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureRulesManagement();
}
}
}

81
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementDbContextModelBuilderExtensions.cs

@ -0,0 +1,81 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using System;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
public static class RulesManagementDbContextModelBuilderExtensions
{
public static void ConfigureRulesManagement(
[NotNull] this ModelBuilder builder,
[CanBeNull] Action<RulesManagementModelBuilderConfigurationOptions> optionsAction = null)
{
Check.NotNull(builder, nameof(builder));
var options = new RulesManagementModelBuilderConfigurationOptions(
RulesManagementDbProperties.DbTablePrefix,
RulesManagementDbProperties.DbSchema
);
optionsAction?.Invoke(options);
builder.Entity<EntityRuleParam>(b =>
{
b.ToTable(options.TablePrefix + "EntityRuleParams", options.Schema);
b.ConfigureMultiTenant();
b.ConfigureExtraProperties();
b.Property(x => x.Id).ValueGeneratedNever();
b.Property(rp => rp.Name).HasMaxLength(EntityRuleParamConsts.MaxNameLength).IsRequired();
b.Property(rp => rp.Expression).HasMaxLength(EntityRuleParamConsts.MaxExpressionLength).IsRequired();
b.HasIndex(rp => rp.Name);
});
builder.Entity<EntityRule>(b =>
{
b.ToTable(options.TablePrefix + "EntityRules", options.Schema);
b.ConfigureByConvention();
b.Property(x => x.Id).ValueGeneratedNever();
b.Property(r => r.Name).HasMaxLength(EntityRuleConsts.MaxNameLength).IsRequired();
b.Property(r => r.Expression).HasMaxLength(EntityRuleConsts.MaxExpressionLength).IsRequired();
b.Property(r => r.Operator).HasMaxLength(EntityRuleConsts.MaxOperatorLength);
b.Property(r => r.DisplayName).HasMaxLength(EntityRuleConsts.MaxDisplayNameLength);
b.Property(r => r.ErrorMessage).HasMaxLength(EntityRuleConsts.MaxErrorMessageLength);
b.HasMany(r => r.SubRules).WithOne().HasForeignKey(r => r.RuleId).IsRequired();
b.HasMany(r => r.InjectRules).WithOne().HasForeignKey(r => r.InjectId).IsRequired();
b.HasMany(r => r.Params).WithOne().HasForeignKey(r => r.RuleId).IsRequired();
b.HasIndex(r => r.Name);
});
builder.Entity<EntityRuleGroup>(b =>
{
b.ToTable(options.TablePrefix + "EntityRuleGroups", options.Schema);
b.ConfigureByConvention();
b.Property(x => x.Id).ValueGeneratedNever();
b.Property(rg => rg.Name).HasMaxLength(EntityRuleGroupConsts.MaxNameLength).IsRequired();
b.Property(rg => rg.EntityFullTypeName).HasMaxLength(EntityRuleGroupConsts.MaxEntiyFullTypeNameLength).IsRequired();
b.Property(rg => rg.DisplayName).HasMaxLength(EntityRuleGroupConsts.MaxDisplayNameLength);
b.HasMany(rg => rg.Rules).WithOne().HasForeignKey(rg => rg.GroupId).IsRequired();
b.HasMany(rg => rg.InjectRules).WithOne().HasForeignKey(rg => rg.InjectId).IsRequired();
b.HasIndex(uc => uc.Name);
});
}
}
}

32
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementEfCoreQueryableExtensions.cs

@ -0,0 +1,32 @@
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
public static class RulesManagementEfCoreQueryableExtensions
{
public static IQueryable<EntityRuleGroup> IncludeDetails(this IQueryable<EntityRuleGroup> queryable, bool include = true)
{
if (!include)
{
return queryable;
}
return queryable
.Include(x => x.Rules)
.Include(x => x.InjectRules);
}
public static IQueryable<EntityRule> IncludeDetails(this IQueryable<EntityRule> queryable, bool include = true)
{
if (!include)
{
return queryable;
}
return queryable
.Include(x => x.InjectRules)
.Include(x => x.Params);
}
}
}

15
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.EntityFrameworkCore/LINGYUN/Abp/RulesManagement/EntityFrameworkCore/RulesManagementModelBuilderConfigurationOptions.cs

@ -0,0 +1,15 @@
using JetBrains.Annotations;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Abp.RulesManagement.EntityFrameworkCore
{
public class RulesManagementModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions
{
public RulesManagementModelBuilderConfigurationOptions(
[NotNull] string tablePrefix,
[CanBeNull] string schema)
: base(tablePrefix, schema)
{
}
}
}

8
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi.Client/Class1.cs

@ -0,0 +1,8 @@
using System;
namespace LINGYUN.Abp.RulesManagement.HttpApi.Client
{
public class Class1
{
}
}

18
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi.Client/LINGYUN.Abp.RulesManagement.HttpApi.Client.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Http.Client" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\RulesManagement\" />
</ItemGroup>
</Project>

8
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi/Class1.cs

@ -0,0 +1,8 @@
using System;
namespace LINGYUN.Abp.RulesManagement.HttpApi
{
public class Class1
{
}
}

18
aspnet-core/modules/rules-management/LINGYUN.Abp.RulesManagement.HttpApi/LINGYUN.Abp.RulesManagement.HttpApi.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\RulesManagement\" />
</ItemGroup>
</Project>

9
aspnet-core/modules/rules-management/README.md

@ -0,0 +1,9 @@
# LINGYUN.Abp.RulesManagement
规则引擎管理
想法很美好,现实很残酷,.NET平台还没有Java阵营那么强大的规则引擎,目前还在研究NRules.Language库,这个库应该可以实现简单的规则动态管理
## 配置使用
待完善
Loading…
Cancel
Save