60 changed files with 1738 additions and 134 deletions
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,7 +0,0 @@ |
|||||
# LINGYUN.Abp.RulesEngine |
|
||||
|
|
||||
规则引擎 [microsoft/RulesEngine](https://github.com/microsoft/RulesEngine) (RulesEngine) 实现 |
|
||||
|
|
||||
## 配置使用 |
|
||||
|
|
||||
待完善 |
|
||||
@ -0,0 +1,8 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace LINGYUN.Abp.RulesManagement |
||||
|
{ |
||||
|
public class Class1 |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -0,0 +1,8 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace LINGYUN.Abp.RulesManagement.Application |
||||
|
{ |
||||
|
public class Class1 |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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> |
||||
@ -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"); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.RulesManagement.Localization |
||||
|
{ |
||||
|
[LocalizationResourceName("AbpRulesManagement")] |
||||
|
public class RulesResource |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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)); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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 }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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 }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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 }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.RulesManagement |
||||
|
{ |
||||
|
public interface IEntityRuleDataSeeder |
||||
|
{ |
||||
|
Task SeedAsync(EntityRuleInGroup group); |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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"; |
||||
|
} |
||||
|
} |
||||
@ -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>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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>(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace LINGYUN.Abp.RulesManagement.HttpApi.Client |
||||
|
{ |
||||
|
public class Class1 |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -0,0 +1,8 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace LINGYUN.Abp.RulesManagement.HttpApi |
||||
|
{ |
||||
|
public class Class1 |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -0,0 +1,9 @@ |
|||||
|
# LINGYUN.Abp.RulesManagement |
||||
|
|
||||
|
规则引擎管理 |
||||
|
|
||||
|
想法很美好,现实很残酷,.NET平台还没有Java阵营那么强大的规则引擎,目前还在研究NRules.Language库,这个库应该可以实现简单的规则动态管理 |
||||
|
|
||||
|
## 配置使用 |
||||
|
|
||||
|
待完善 |
||||
Loading…
Reference in new issue