41 changed files with 25 additions and 1054 deletions
@ -1,31 +0,0 @@ |
|||||
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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,22 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
|
|
||||
<Import Project="..\..\..\common.props" /> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>netstandard2.0</TargetFramework> |
|
||||
<RootNamespace /> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="NRules" Version="0.9.0" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\LINGYUN.Abp.Rules\LINGYUN.Abp.Rules.csproj" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<Folder Include="LINGYUN\Abp\Rules\NRules\" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,14 +0,0 @@ |
|||||
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>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,44 +0,0 @@ |
|||||
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(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
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); |
|
||||
} |
|
||||
} |
|
||||
@ -1,60 +0,0 @@ |
|||||
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(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,55 +0,0 @@ |
|||||
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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,14 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
|
|
||||
<Import Project="..\..\..\common.props" /> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>netstandard2.0</TargetFramework> |
|
||||
<RootNamespace /> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="4.3.0" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,16 +0,0 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Volo.Abp.Domain; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
[DependsOn( |
|
||||
typeof(AbpDddDomainModule))] |
|
||||
public class AbpRulesModule : AbpModule |
|
||||
{ |
|
||||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
context.Services.OnRegistred(EntityChangedRulesInterceptorRegistrar.RegisterIfNeeded); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,48 +0,0 @@ |
|||||
using System; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.DynamicProxy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public class EntityChangedRulesInterceptor : AbpInterceptor, ITransientDependency |
|
||||
{ |
|
||||
protected IRuleFinder RuleFinder { get; } |
|
||||
protected IEntityRuleContributor EntityRuleContributor { get; } |
|
||||
|
|
||||
public EntityChangedRulesInterceptor( |
|
||||
IRuleFinder ruleFinder, |
|
||||
IEntityRuleContributor entityRuleContributor) |
|
||||
{ |
|
||||
RuleFinder = ruleFinder; |
|
||||
EntityRuleContributor = entityRuleContributor; |
|
||||
} |
|
||||
|
|
||||
public override async Task InterceptAsync(IAbpMethodInvocation invocation) |
|
||||
{ |
|
||||
var entityObj = invocation.Arguments.First(); |
|
||||
// TODO: 针对实体的变更执行一次定义的规则
|
|
||||
// IBasicRepository.InsertAsync || IBasicRepository.UpdateAsync || IBasicRepository.DeleteAsync
|
|
||||
if (entityObj != null && entityObj is IEntity entity) |
|
||||
{ |
|
||||
await ApplyEntityRuleAsync(entity); |
|
||||
} |
|
||||
|
|
||||
await invocation.ProceedAsync(); |
|
||||
} |
|
||||
|
|
||||
protected virtual async Task ApplyEntityRuleAsync(IEntity entity) |
|
||||
{ |
|
||||
Type entityType = ProxyHelper.GetUnProxiedType(entity); |
|
||||
// 加载规则列表
|
|
||||
var groups = await RuleFinder.GetRuleGroupsAsync(entityType); |
|
||||
if (groups.Any()) |
|
||||
{ |
|
||||
// 应用规则
|
|
||||
await EntityRuleContributor.ApplyAsync(new EntityRuleContext(groups, entity)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,28 +0,0 @@ |
|||||
using System; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.Domain.Repositories; |
|
||||
using Volo.Abp.DynamicProxy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public static class EntityChangedRulesInterceptorRegistrar |
|
||||
{ |
|
||||
public static void RegisterIfNeeded(IOnServiceRegistredContext context) |
|
||||
{ |
|
||||
if (ShouldIntercept(context.ImplementationType)) |
|
||||
{ |
|
||||
context.Interceptors.TryAdd<EntityChangedRulesInterceptor>(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static bool ShouldIntercept(Type type) |
|
||||
{ |
|
||||
// 拦截器的要求
|
|
||||
// 1、继承自IBasicRepository的仓储
|
|
||||
// 2、继承自INeedRule接口的实体
|
|
||||
return !DynamicProxyIgnoreTypes.Contains(type) && |
|
||||
type.IsAssignableTo(typeof(IBasicRepository<>)) && |
|
||||
type.GetGenericTypeDefinition().IsAssignableTo(typeof(INeedRule)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,18 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public class EntityRuleContext |
|
||||
{ |
|
||||
public List<RuleGroup> Groups { get; } |
|
||||
public IEntity Entity { get; } |
|
||||
public EntityRuleContext( |
|
||||
List<RuleGroup> groups, |
|
||||
IEntity entity) |
|
||||
{ |
|
||||
Groups = groups; |
|
||||
Entity = entity; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,8 +0,0 @@ |
|||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public enum ErrorType |
|
||||
{ |
|
||||
Warning = 0, |
|
||||
Error = 1 |
|
||||
} |
|
||||
} |
|
||||
@ -1,7 +0,0 @@ |
|||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public enum ExpressionType |
|
||||
{ |
|
||||
LambdaExpression = 0 |
|
||||
} |
|
||||
} |
|
||||
@ -1,9 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public interface IEntityRuleContributor |
|
||||
{ |
|
||||
Task ApplyAsync(EntityRuleContext context); |
|
||||
} |
|
||||
} |
|
||||
@ -1,6 +0,0 @@ |
|||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public interface INeedRule |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,11 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public interface IRuleFinder |
|
||||
{ |
|
||||
Task<List<RuleGroup>> GetRuleGroupsAsync(Type entityType); |
|
||||
} |
|
||||
} |
|
||||
@ -1,13 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public class NullEntityRuleContributor : IEntityRuleContributor, ISingletonDependency |
|
||||
{ |
|
||||
public Task ApplyAsync(EntityRuleContext context) |
|
||||
{ |
|
||||
return Task.CompletedTask; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public class NullRuleFinder : IRuleFinder, ISingletonDependency |
|
||||
{ |
|
||||
public Task<List<RuleGroup>> GetRuleGroupsAsync(Type entityType) |
|
||||
{ |
|
||||
return Task.FromResult(new List<RuleGroup>()); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,90 +0,0 @@ |
|||||
using JetBrains.Annotations; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using Volo.Abp; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// ref: https://github.com/microsoft/RulesEngine/blob/master/src/RulesEngine/RulesEngine/Models/Rule.cs
|
|
||||
/// </summary>
|
|
||||
public class Rule |
|
||||
{ |
|
||||
[NotNull] |
|
||||
public string Name { get; set; } |
|
||||
public string Operator { get; set; } |
|
||||
public string ErrorMessage { get; set; } |
|
||||
public DateTime CreationTime { get; set; } |
|
||||
public ErrorType ErrorType { get; set; } |
|
||||
public ExpressionType? ExpressionType { get; set; } |
|
||||
public List<Rule> Rules { get; set; } |
|
||||
public List<string> InjectRules { get; set; } |
|
||||
public List<RuleParam> Params { get; set; } |
|
||||
public string Expression { get; set; } |
|
||||
public string SuccessEvent { get; set; } |
|
||||
protected Rule() { } |
|
||||
public Rule( |
|
||||
[NotNull] string name, |
|
||||
string operation, |
|
||||
DateTime creationTime, |
|
||||
string expression = null, |
|
||||
string successEvent = null, |
|
||||
ErrorType errorType = ErrorType.Warning, |
|
||||
ExpressionType? expressionType = null) |
|
||||
{ |
|
||||
Check.NotNullOrWhiteSpace(name, nameof(name)); |
|
||||
|
|
||||
Name = name; |
|
||||
Operator = operation; |
|
||||
CreationTime = creationTime; |
|
||||
Expression = expression; |
|
||||
SuccessEvent = successEvent; |
|
||||
ErrorType = errorType; |
|
||||
ExpressionType = expressionType; |
|
||||
|
|
||||
Rules = new List<Rule>(); |
|
||||
Params = new List<RuleParam>(); |
|
||||
InjectRules = new List<string>(); |
|
||||
} |
|
||||
|
|
||||
public Rule CreateChildren(Rule rule) |
|
||||
{ |
|
||||
Rules.Add(rule); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public Rule WithParam(RuleParam param) |
|
||||
{ |
|
||||
Params.AddIfNotContains(param); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public Rule InjectRule(string ruleName) |
|
||||
{ |
|
||||
InjectRules.AddIfNotContains(ruleName); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public override int GetHashCode() |
|
||||
{ |
|
||||
return Name.GetHashCode(); |
|
||||
} |
|
||||
|
|
||||
public override bool Equals(object obj) |
|
||||
{ |
|
||||
if (obj == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if (obj is Rule rule) |
|
||||
{ |
|
||||
return rule.Name.Equals(Name); |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,53 +0,0 @@ |
|||||
using JetBrains.Annotations; |
|
||||
using System.Collections.Generic; |
|
||||
using Volo.Abp; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public class RuleGroup |
|
||||
{ |
|
||||
[NotNull] |
|
||||
public string Name { get; set; } |
|
||||
public List<string> InjectRules { get; set; } |
|
||||
public List<Rule> Rules { get; } |
|
||||
protected RuleGroup() { } |
|
||||
public RuleGroup( |
|
||||
[NotNull] string name) |
|
||||
{ |
|
||||
Check.NotNullOrWhiteSpace(name, nameof(name)); |
|
||||
|
|
||||
Name = name; |
|
||||
|
|
||||
Rules = new List<Rule>(); |
|
||||
InjectRules = new List<string>(); |
|
||||
} |
|
||||
|
|
||||
public RuleGroup WithInjectRule(string ruleName) |
|
||||
{ |
|
||||
InjectRules.AddIfNotContains(ruleName); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public RuleGroup WithInjectRule(IEnumerable<string> ruleNames) |
|
||||
{ |
|
||||
InjectRules.AddIfNotContains(ruleNames); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public RuleGroup WithRule(Rule rule) |
|
||||
{ |
|
||||
Rules.AddIfNotContains(rule); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public RuleGroup WithRule(IEnumerable<Rule> rules) |
|
||||
{ |
|
||||
Rules.AddIfNotContains(rules); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,35 +0,0 @@ |
|||||
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,45 +0,0 @@ |
|||||
using JetBrains.Annotations; |
|
||||
using Volo.Abp; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Rules |
|
||||
{ |
|
||||
public class RuleParam |
|
||||
{ |
|
||||
[NotNull] |
|
||||
public string Name { get; set; } |
|
||||
|
|
||||
[NotNull] |
|
||||
public string Expression { get; set; } |
|
||||
|
|
||||
protected RuleParam() { } |
|
||||
public RuleParam( |
|
||||
[NotNull] string name, |
|
||||
[NotNull] string expression) |
|
||||
{ |
|
||||
Check.NotNullOrWhiteSpace(name, nameof(name)); |
|
||||
Check.NotNullOrWhiteSpace(expression, nameof(expression)); |
|
||||
|
|
||||
Name = name; |
|
||||
Expression = expression; |
|
||||
} |
|
||||
|
|
||||
public override int GetHashCode() |
|
||||
{ |
|
||||
return Name.GetHashCode(); |
|
||||
} |
|
||||
|
|
||||
public override bool Equals(object obj) |
|
||||
{ |
|
||||
if (obj == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if (obj is RuleParam param) |
|
||||
{ |
|
||||
return param.Name.Equals(Name); |
|
||||
} |
|
||||
return base.Equals(obj); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,7 +0,0 @@ |
|||||
# LINGYUN.Abp.Rules |
|
||||
|
|
||||
规则引擎定义 |
|
||||
|
|
||||
## 配置使用 |
|
||||
|
|
||||
待完善 |
|
||||
@ -1,20 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|
||||
|
|
||||
<Import Project="..\..\..\common.props" /> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>net5.0</TargetFramework> |
|
||||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|
||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|
||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|
||||
<IsPackable>true</IsPackable> |
|
||||
<OutputType>Library</OutputType> |
|
||||
<RootNamespace /> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\LINGYUN.Abp.Dapr.Actors.IdentityModel\LINGYUN.Abp.Dapr.Actors.IdentityModel.csproj" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||
<PropertyGroup> |
|
||||
<ActiveDebugProfile>IIS Express</ActiveDebugProfile> |
|
||||
</PropertyGroup> |
|
||||
</Project> |
|
||||
@ -1,10 +0,0 @@ |
|||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Dapr.Actors.IdentityModel.Web |
|
||||
{ |
|
||||
[DependsOn( |
|
||||
typeof(AbpDaprActorsIdentityModelModule))] |
|
||||
public class AbpDaprActorsIdentityModelWebModule : AbpModule |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,51 +0,0 @@ |
|||||
using LINGYUN.Abp.Dapr.Actors.Authentication; |
|
||||
using Microsoft.AspNetCore.Authentication; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using System.Net.Http.Headers; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.IdentityModel; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Dapr.Actors.IdentityModel |
|
||||
{ |
|
||||
[Dependency(ReplaceServices = true)] |
|
||||
public class HttpContextIdentityModelDaprActorProxyAuthenticator : IdentityModelDaprActorProxyAuthenticator |
|
||||
{ |
|
||||
public IHttpContextAccessor HttpContextAccessor { get; set; } |
|
||||
|
|
||||
public HttpContextIdentityModelDaprActorProxyAuthenticator( |
|
||||
IIdentityModelAuthenticationService identityModelAuthenticationService) |
|
||||
: base(identityModelAuthenticationService) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public override async Task AuthenticateAsync(DaprActorProxyAuthenticateContext context) |
|
||||
{ |
|
||||
if (context.RemoteService.GetUseCurrentAccessToken() != false) |
|
||||
{ |
|
||||
var accessToken = await GetAccessTokenFromHttpContextOrNullAsync(); |
|
||||
if (accessToken != null) |
|
||||
{ |
|
||||
context.Handler.PreConfigure(request => |
|
||||
{ |
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); |
|
||||
}); |
|
||||
return; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
await base.AuthenticateAsync(context); |
|
||||
} |
|
||||
|
|
||||
protected virtual async Task<string> GetAccessTokenFromHttpContextOrNullAsync() |
|
||||
{ |
|
||||
var httpContext = HttpContextAccessor?.HttpContext; |
|
||||
if (httpContext == null) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
return await httpContext.GetTokenAsync("access_token"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,27 +0,0 @@ |
|||||
{ |
|
||||
"iisSettings": { |
|
||||
"windowsAuthentication": false, |
|
||||
"anonymousAuthentication": true, |
|
||||
"iisExpress": { |
|
||||
"applicationUrl": "http://localhost:25348/", |
|
||||
"sslPort": 44377 |
|
||||
} |
|
||||
}, |
|
||||
"profiles": { |
|
||||
"IIS Express": { |
|
||||
"commandName": "IISExpress", |
|
||||
"launchBrowser": true, |
|
||||
"environmentVariables": { |
|
||||
"ASPNETCORE_ENVIRONMENT": "Development" |
|
||||
} |
|
||||
}, |
|
||||
"LINGYUN.Abp.Dapr.Actors.IdentityModel.Web": { |
|
||||
"commandName": "Project", |
|
||||
"launchBrowser": true, |
|
||||
"environmentVariables": { |
|
||||
"ASPNETCORE_ENVIRONMENT": "Development" |
|
||||
}, |
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,19 +0,0 @@ |
|||||
# LINGYUN.Abp.Dapr.Actors.IdentityModel.Web |
|
||||
|
|
||||
Dapr.Actors内部使用Http进行服务间调用,此模块用于获取应用当前状态中的身份令牌并传递到远程Actor服务 |
|
||||
|
|
||||
## 配置使用 |
|
||||
|
|
||||
模块按需引用 |
|
||||
|
|
||||
```csharp |
|
||||
[DependsOn(typeof(AbpDaprActorsIdentityModelWebModule))] |
|
||||
public class YouProjectModule : AbpModule |
|
||||
{ |
|
||||
// other |
|
||||
} |
|
||||
``` |
|
||||
## 配置项说明 |
|
||||
|
|
||||
|
|
||||
## 其他 |
|
||||
@ -1,18 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
|
|
||||
<Import Project="..\..\..\common.props" /> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>net5.0</TargetFramework> |
|
||||
<RootNamespace /> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Volo.Abp.IdentityModel" Version="4.3.0" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\LINGYUN.Abp.Dapr.Actors\LINGYUN.Abp.Dapr.Actors.csproj" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,54 +0,0 @@ |
|||||
using JetBrains.Annotations; |
|
||||
using System.Collections.Generic; |
|
||||
using Volo.Abp; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Dapr.Actors |
|
||||
{ |
|
||||
public static class DaprActorConfigurationExtensions |
|
||||
{ |
|
||||
public const string IdentityClientName = "IdentityClient"; |
|
||||
public const string UseCurrentAccessTokenName = "UseCurrentAccessToken"; |
|
||||
|
|
||||
[CanBeNull] |
|
||||
public static string GetIdentityClient([NotNull] this DaprActorConfiguration configuration) |
|
||||
{ |
|
||||
Check.NotNullOrEmpty(configuration, nameof(configuration)); |
|
||||
|
|
||||
return configuration.GetOrDefault(IdentityClientName); |
|
||||
} |
|
||||
|
|
||||
public static DaprActorConfiguration SetIdentityClient([NotNull] this DaprActorConfiguration configuration, [CanBeNull] string value) |
|
||||
{ |
|
||||
configuration[IdentityClientName] = value; |
|
||||
return configuration; |
|
||||
} |
|
||||
|
|
||||
[CanBeNull] |
|
||||
public static bool? GetUseCurrentAccessToken([NotNull] this DaprActorConfiguration configuration) |
|
||||
{ |
|
||||
Check.NotNullOrEmpty(configuration, nameof(configuration)); |
|
||||
|
|
||||
var value = configuration.GetOrDefault(UseCurrentAccessTokenName); |
|
||||
if (value == null) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
return bool.Parse(value); |
|
||||
} |
|
||||
|
|
||||
public static DaprActorConfiguration SetUseCurrentAccessToken([NotNull] this DaprActorConfiguration configuration, [CanBeNull] bool? value) |
|
||||
{ |
|
||||
if (value == null) |
|
||||
{ |
|
||||
configuration.Remove(UseCurrentAccessTokenName); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
configuration[UseCurrentAccessTokenName] = value.Value.ToString().ToLowerInvariant(); |
|
||||
} |
|
||||
|
|
||||
return configuration; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,13 +0,0 @@ |
|||||
using Volo.Abp.IdentityModel; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Dapr.Actors.IdentityModel |
|
||||
{ |
|
||||
[DependsOn( |
|
||||
typeof(AbpDaprActorsModule), |
|
||||
typeof(AbpIdentityModelModule) |
|
||||
)] |
|
||||
public class AbpDaprActorsIdentityModelModule : AbpModule |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,66 +0,0 @@ |
|||||
using LINGYUN.Abp.Dapr.Actors.Authentication; |
|
||||
using LINGYUN.Abp.Dapr.Actors.DynamicProxying; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using Microsoft.Extensions.Logging.Abstractions; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Net.Http.Headers; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.IdentityModel; |
|
||||
|
|
||||
namespace LINGYUN.Abp.Dapr.Actors.IdentityModel |
|
||||
{ |
|
||||
[Dependency(ReplaceServices = true)] |
|
||||
public class IdentityModelDaprActorProxyAuthenticator : IDaprActorProxyAuthenticator, ITransientDependency |
|
||||
{ |
|
||||
protected AbpIdentityClientOptions ClientOptions { get; } |
|
||||
protected IIdentityModelAuthenticationService IdentityModelAuthenticationService { get; } |
|
||||
|
|
||||
public ILogger<IdentityModelDaprActorProxyAuthenticator> Logger { get; set; } |
|
||||
|
|
||||
public IdentityModelDaprActorProxyAuthenticator( |
|
||||
IIdentityModelAuthenticationService identityModelAuthenticationService) |
|
||||
{ |
|
||||
IdentityModelAuthenticationService = identityModelAuthenticationService; |
|
||||
Logger = NullLogger<IdentityModelDaprActorProxyAuthenticator>.Instance; |
|
||||
} |
|
||||
|
|
||||
public virtual async Task AuthenticateAsync(DaprActorProxyAuthenticateContext context) |
|
||||
{ |
|
||||
var identityClientName = context.RemoteService.GetIdentityClient(); |
|
||||
var configuration = GetClientConfiguration(identityClientName); |
|
||||
if (configuration == null) |
|
||||
{ |
|
||||
Logger.LogWarning($"Could not find {nameof(IdentityClientConfiguration)} for {identityClientName}. Either define a configuration for {identityClientName} or set a default configuration."); |
|
||||
return; |
|
||||
} |
|
||||
var accessToken = await IdentityModelAuthenticationService.GetAccessTokenAsync(configuration); |
|
||||
if (accessToken == null) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
SetAccessToken(context.Handler, accessToken); |
|
||||
} |
|
||||
|
|
||||
protected virtual void SetAccessToken(DaprHttpClientHandler handler, string accessToken) |
|
||||
{ |
|
||||
handler.PreConfigure(request => |
|
||||
{ |
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private IdentityClientConfiguration GetClientConfiguration(string identityClientName = null) |
|
||||
{ |
|
||||
if (identityClientName.IsNullOrEmpty()) |
|
||||
{ |
|
||||
return ClientOptions.IdentityClients.Default; |
|
||||
} |
|
||||
|
|
||||
return ClientOptions.IdentityClients.GetOrDefault(identityClientName) ?? |
|
||||
ClientOptions.IdentityClients.Default; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,19 +0,0 @@ |
|||||
# LINGYUN.Abp.Dapr.Actors.IdentityModel |
|
||||
|
|
||||
Dapr.Actors内部使用Http进行服务间调用,此模块用于传递服务间调用令牌 |
|
||||
|
|
||||
## 配置使用 |
|
||||
|
|
||||
模块按需引用 |
|
||||
|
|
||||
```csharp |
|
||||
[DependsOn(typeof(AbpDaprActorsIdentityModelModule))] |
|
||||
public class YouProjectModule : AbpModule |
|
||||
{ |
|
||||
// other |
|
||||
} |
|
||||
``` |
|
||||
## 配置项说明 |
|
||||
|
|
||||
|
|
||||
## 其他 |
|
||||
Loading…
Reference in new issue