mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-24 05:23:33 +08:00
Replace dlr scripting implementation with the new lightweight engine
DLR scripting engine still available in new Orchard.Scripting.Dlr module --HG-- branch : dev rename : src/Orchard.Web/Modules/Orchard.Scripting/ScriptingManager.cs => src/Orchard.Web/Modules/Orchard.Scripting/ScriptExpressionEvaluator.cs
This commit is contained in:
@@ -2,30 +2,24 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Orchard.Scripting;
|
using Orchard.Scripting;
|
||||||
using Orchard.Tests.Stubs;
|
using Orchard.Tests.Stubs;
|
||||||
using Orchard.Widgets.Services;
|
|
||||||
|
|
||||||
namespace Orchard.Tests.Modules.Scripting {
|
namespace Orchard.Tests.Modules.Scripting {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class SimpleScriptingTests {
|
public class SimpleScriptingTests {
|
||||||
[Test]
|
[Test]
|
||||||
public void EngineThrowsSyntaxErrors() {
|
public void EngineThrowsSyntaxErrors() {
|
||||||
var engine = new ScriptingEngine(Enumerable.Empty<IGlobalMethodProvider>(), new StubCacheManager());
|
var engine = new ScriptExpressionEvaluator(new StubCacheManager());
|
||||||
Assert.That(() => engine.Matches("true+"), Throws.Exception);
|
Assert.That(() => engine.Evaluate("true+", Enumerable.Empty<IGlobalMethodProvider>()), Throws.Exception);
|
||||||
}
|
|
||||||
[Test]
|
|
||||||
public void EngineThrowsEvalErrors() {
|
|
||||||
var engine = new ScriptingEngine(Enumerable.Empty<IGlobalMethodProvider>(), new StubCacheManager());
|
|
||||||
Assert.That(() => engine.Matches("1 + 1"), Throws.Exception);
|
|
||||||
}
|
}
|
||||||
[Test]
|
[Test]
|
||||||
public void EngineUnderstandsPrimitiveValues() {
|
public void EngineUnderstandsPrimitiveValues() {
|
||||||
var engine = new ScriptingEngine(Enumerable.Empty<IGlobalMethodProvider>(), new StubCacheManager());
|
var engine = new ScriptExpressionEvaluator(new StubCacheManager());
|
||||||
Assert.That(engine.Matches("true"), Is.True);
|
Assert.That(engine.Evaluate("true", Enumerable.Empty<IGlobalMethodProvider>()), Is.True);
|
||||||
}
|
}
|
||||||
[Test]
|
[Test]
|
||||||
public void EngineUnderstandsPrimitiveValues2() {
|
public void EngineUnderstandsPrimitiveValues2() {
|
||||||
var engine = new ScriptingEngine(Enumerable.Empty<IGlobalMethodProvider>(), new StubCacheManager());
|
var engine = new ScriptExpressionEvaluator(new StubCacheManager());
|
||||||
Assert.That(engine.Matches("true and true"), Is.True);
|
Assert.That(engine.Evaluate("true and true", Enumerable.Empty<IGlobalMethodProvider>()), Is.True);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,5 +7,6 @@ OrchardVersion: 0.8.0
|
|||||||
Description: The DLR scripting module enables the possibility to execute scripts using the DLR.
|
Description: The DLR scripting module enables the possibility to execute scripts using the DLR.
|
||||||
Features:
|
Features:
|
||||||
Orchard.Scripting.Dlr:
|
Orchard.Scripting.Dlr:
|
||||||
Description: DLR Scripting support.
|
Description: DLR scripting support.
|
||||||
|
Dependencies: Orchard.Scripting
|
||||||
Category: Scripting
|
Category: Scripting
|
@@ -62,6 +62,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Services\RubyScriptExpressionEvaluator.cs" />
|
||||||
<Compile Include="Services\IScriptingManager.cs" />
|
<Compile Include="Services\IScriptingManager.cs" />
|
||||||
<Compile Include="Services\IScriptingRuntime.cs" />
|
<Compile Include="Services\IScriptingRuntime.cs" />
|
||||||
<Compile Include="Services\RubyScriptingRuntime.cs" />
|
<Compile Include="Services\RubyScriptingRuntime.cs" />
|
||||||
@@ -73,6 +74,10 @@
|
|||||||
<Name>Orchard.Framework</Name>
|
<Name>Orchard.Framework</Name>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\Orchard.Scripting\Orchard.Scripting.csproj">
|
||||||
|
<Project>{99002B65-86F7-415E-BF4A-381AA8AB9CCC}</Project>
|
||||||
|
<Name>Orchard.Scripting</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Module.txt" />
|
<Content Include="Module.txt" />
|
||||||
|
@@ -0,0 +1,71 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Scripting.Hosting;
|
||||||
|
using Orchard.Caching;
|
||||||
|
|
||||||
|
namespace Orchard.Scripting.Dlr.Services {
|
||||||
|
public class RubyScriptExpressionEvaluator : IScriptExpressionEvaluator {
|
||||||
|
private readonly IScriptingManager _scriptingManager;
|
||||||
|
private readonly ICacheManager _cacheManager;
|
||||||
|
|
||||||
|
public RubyScriptExpressionEvaluator(IScriptingManager scriptingManager, ICacheManager cacheManager) {
|
||||||
|
_scriptingManager = scriptingManager;
|
||||||
|
_cacheManager = cacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Evaluate(string expression, IEnumerable<IGlobalMethodProvider> providers) {
|
||||||
|
object execContextType = _cacheManager.Get("---", ctx => (object)_scriptingManager.ExecuteExpression(@"
|
||||||
|
class ExecBlock
|
||||||
|
def initialize(callbacks)
|
||||||
|
@callbacks = callbacks
|
||||||
|
end
|
||||||
|
def method_missing(name, *args, &block)
|
||||||
|
@callbacks.send(name, args, &block);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class ExecContext
|
||||||
|
class << self
|
||||||
|
def alloc(thing)
|
||||||
|
instance_eval 'self.new {' + thing + '}'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def initialize(&block)
|
||||||
|
@block = block
|
||||||
|
end
|
||||||
|
def evaluate(callbacks)
|
||||||
|
ExecBlock.new(callbacks).instance_eval(&@block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ExecContext
|
||||||
|
"));
|
||||||
|
var ops = _cacheManager.Get("----", ctx => (ObjectOperations)_scriptingManager.ExecuteOperation(x => x));
|
||||||
|
object execContext = _cacheManager.Get(expression, ctx => (object)ops.InvokeMember(execContextType, "alloc", expression));
|
||||||
|
dynamic result = ops.InvokeMember(execContext, "evaluate", new CallbackApi(this, providers));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CallbackApi {
|
||||||
|
private readonly RubyScriptExpressionEvaluator _ruleManager;
|
||||||
|
private readonly IEnumerable<IGlobalMethodProvider> _providers;
|
||||||
|
|
||||||
|
public CallbackApi(RubyScriptExpressionEvaluator ruleManager, IEnumerable<IGlobalMethodProvider> providers) {
|
||||||
|
_ruleManager = ruleManager;
|
||||||
|
_providers = providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object send(string name, IList<object> args) {
|
||||||
|
return _ruleManager.Evaluate(_providers, name, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object Evaluate(IEnumerable<IGlobalMethodProvider> providers, string name, IList<object> args) {
|
||||||
|
GlobalMethodContext ruleContext = new GlobalMethodContext { FunctionName = name, Arguments = args.ToArray() };
|
||||||
|
|
||||||
|
foreach (var ruleProvider in providers) {
|
||||||
|
ruleProvider.Process(ruleContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ruleContext.Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Orchard.Scripting {
|
||||||
|
public interface IGlobalMethodProvider {
|
||||||
|
void Process(GlobalMethodContext context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GlobalMethodContext {
|
||||||
|
public string FunctionName { get; set; }
|
||||||
|
public IList<object> Arguments { get; set; }
|
||||||
|
public object Result { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,7 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Orchard.Scripting {
|
namespace Orchard.Scripting {
|
||||||
public interface IScriptExpressionEvaluator : ISingletonDependency {
|
public interface IScriptExpressionEvaluator : ISingletonDependency {
|
||||||
|
object Evaluate(string expression, IEnumerable<IGlobalMethodProvider> providers);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -6,6 +6,11 @@ Version: 0.8.0
|
|||||||
OrchardVersion: 0.8.0
|
OrchardVersion: 0.8.0
|
||||||
Description: The scripting module enables the possibility to execute scripts using a simple custom scripting language.
|
Description: The scripting module enables the possibility to execute scripts using a simple custom scripting language.
|
||||||
Features:
|
Features:
|
||||||
Orchard.Scripting.:
|
Orchard.Scripting:
|
||||||
Description: Simple scripting support.
|
Description: Scripting support.
|
||||||
|
Category: Scripting
|
||||||
|
Orchard.Scripting.Lightweight:
|
||||||
|
Name: Lightweight scripting
|
||||||
|
Description: Custom lightweight and simple scripting language.
|
||||||
|
Dependencies: Orchard.Scripting
|
||||||
Category: Scripting
|
Category: Scripting
|
@@ -54,6 +54,7 @@
|
|||||||
<Compile Include="Ast\IAstNodeWithToken.cs" />
|
<Compile Include="Ast\IAstNodeWithToken.cs" />
|
||||||
<Compile Include="Ast\MethodCallAstNode.cs" />
|
<Compile Include="Ast\MethodCallAstNode.cs" />
|
||||||
<Compile Include="Ast\UnaryAstNode.cs" />
|
<Compile Include="Ast\UnaryAstNode.cs" />
|
||||||
|
<Compile Include="IGlobalMethodProvider.cs" />
|
||||||
<Compile Include="IScriptExpressionEvaluator.cs" />
|
<Compile Include="IScriptExpressionEvaluator.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Compiler\Interpreter.cs" />
|
<Compile Include="Compiler\Interpreter.cs" />
|
||||||
@@ -63,7 +64,7 @@
|
|||||||
<Compile Include="Compiler\Token.cs" />
|
<Compile Include="Compiler\Token.cs" />
|
||||||
<Compile Include="Compiler\Tokenizer.cs" />
|
<Compile Include="Compiler\Tokenizer.cs" />
|
||||||
<Compile Include="Compiler\TokenKind.cs" />
|
<Compile Include="Compiler\TokenKind.cs" />
|
||||||
<Compile Include="ScriptingManager.cs" />
|
<Compile Include="ScriptExpressionEvaluator.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||||
|
@@ -2,38 +2,24 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Orchard.Caching;
|
using Orchard.Caching;
|
||||||
|
using Orchard.Environment.Extensions;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Scripting.Ast;
|
using Orchard.Scripting.Ast;
|
||||||
using Orchard.Scripting.Compiler;
|
using Orchard.Scripting.Compiler;
|
||||||
|
|
||||||
namespace Orchard.Scripting {
|
namespace Orchard.Scripting {
|
||||||
public class GlobalMethodContext {
|
[OrchardFeature("Orchard.Scripting.Lightweight")]
|
||||||
public string FunctionName { get; set; }
|
public class ScriptExpressionEvaluator : IScriptExpressionEvaluator {
|
||||||
public IList<object> Arguments { get; set; }
|
|
||||||
public object Result { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IGlobalMethodProvider {
|
|
||||||
object Process(GlobalMethodContext context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IScriptingEngine : IDependency {
|
|
||||||
bool Matches(string expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ScriptingEngine : IScriptingEngine {
|
|
||||||
private readonly IEnumerable<IGlobalMethodProvider> _ruleProviders;
|
|
||||||
private readonly ICacheManager _cacheManager;
|
private readonly ICacheManager _cacheManager;
|
||||||
|
|
||||||
public ScriptingEngine(IEnumerable<IGlobalMethodProvider> ruleProviders, ICacheManager cacheManager) {
|
public ScriptExpressionEvaluator(ICacheManager cacheManager) {
|
||||||
_ruleProviders = ruleProviders;
|
|
||||||
_cacheManager = cacheManager;
|
_cacheManager = cacheManager;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
|
|
||||||
public bool Matches(string expression) {
|
public object Evaluate(string expression, IEnumerable<IGlobalMethodProvider> providers) {
|
||||||
var expr = _cacheManager.Get(expression, ctx => {
|
var expr = _cacheManager.Get(expression, ctx => {
|
||||||
var ast = ParseExpression(expression);
|
var ast = ParseExpression(expression);
|
||||||
return new { Tree = ast, Errors = ast.GetErrors().ToList() };
|
return new { Tree = ast, Errors = ast.GetErrors().ToList() };
|
||||||
@@ -44,38 +30,38 @@ namespace Orchard.Scripting {
|
|||||||
throw new OrchardException(T("Syntax error: {0}", expr.Errors.First().Message));
|
throw new OrchardException(T("Syntax error: {0}", expr.Errors.First().Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = EvaluateExpression(expr.Tree);
|
var result = EvaluateExpression(expr.Tree, providers);
|
||||||
if (result.IsError) {
|
if (result.IsError) {
|
||||||
throw new ApplicationException(result.Error.Message);
|
throw new ApplicationException(result.Error.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.IsBool) {
|
return result.Value;
|
||||||
throw new OrchardException(T("Expression is not a boolean value"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.BoolValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AbstractSyntaxTree ParseExpression(string expression) {
|
private AbstractSyntaxTree ParseExpression(string expression) {
|
||||||
return new Parser(expression).Parse();
|
return new Parser(expression).Parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private EvaluationResult EvaluateExpression(AbstractSyntaxTree tree) {
|
private EvaluationResult EvaluateExpression(AbstractSyntaxTree tree, IEnumerable<IGlobalMethodProvider> providers) {
|
||||||
var context = new EvaluationContext {
|
var context = new EvaluationContext {
|
||||||
Tree = tree,
|
Tree = tree,
|
||||||
MethodInvocationCallback = (m, args) => Evaluate(m, args)
|
MethodInvocationCallback = (m, args) => Evaluate(providers, m, args)
|
||||||
};
|
};
|
||||||
return new Interpreter().Evalutate(context);
|
return new Interpreter().Evalutate(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private object Evaluate(string name, IEnumerable<object> args) {
|
private object Evaluate(IEnumerable<IGlobalMethodProvider> globalMethodProviders, string name, IEnumerable<object> args) {
|
||||||
var ruleContext = new GlobalMethodContext() { FunctionName = name, Arguments = args.ToArray() };
|
var globalMethodContext = new GlobalMethodContext {
|
||||||
|
FunctionName = name,
|
||||||
|
Arguments = args.ToArray(),
|
||||||
|
Result = null
|
||||||
|
};
|
||||||
|
|
||||||
foreach (var ruleProvider in _ruleProviders) {
|
foreach (var globalMethodProvider in globalMethodProviders) {
|
||||||
ruleProvider.Process(ruleContext);
|
globalMethodProvider.Process(globalMethodContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ruleContext.Result;
|
return globalMethodContext.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -35,10 +35,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Microsoft.Scripting, Version=1.1.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\..\..\..\lib\dlr\Microsoft.Scripting.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||||
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
@@ -100,10 +96,6 @@
|
|||||||
<Name>Orchard.Framework</Name>
|
<Name>Orchard.Framework</Name>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\Orchard.Scripting.Dlr\Orchard.Scripting.Dlr.csproj">
|
|
||||||
<Project>{2AD6973D-C7BB-416E-89FE-EEE34664E05F}</Project>
|
|
||||||
<Name>Orchard.Scripting.Dlr</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\Orchard.Scripting\Orchard.Scripting.csproj">
|
<ProjectReference Include="..\Orchard.Scripting\Orchard.Scripting.csproj">
|
||||||
<Project>{99002B65-86F7-415E-BF4A-381AA8AB9CCC}</Project>
|
<Project>{99002B65-86F7-415E-BF4A-381AA8AB9CCC}</Project>
|
||||||
<Name>Orchard.Scripting</Name>
|
<Name>Orchard.Scripting</Name>
|
||||||
|
@@ -1,73 +1,55 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Orchard.Scripting.Dlr.Services;
|
using Orchard.Localization;
|
||||||
|
using Orchard.Scripting;
|
||||||
using Orchard.Widgets.Services;
|
using Orchard.Widgets.Services;
|
||||||
using Microsoft.Scripting.Hosting;
|
|
||||||
using Orchard.Caching;
|
|
||||||
|
|
||||||
namespace Orchard.Widgets.RuleEngine {
|
namespace Orchard.Widgets.RuleEngine {
|
||||||
public class RuleManager : IRuleManager {
|
public class RuleManager : IRuleManager {
|
||||||
private readonly IEnumerable<IRuleProvider> _ruleProviders;
|
private readonly IEnumerable<IRuleProvider> _ruleProviders;
|
||||||
private readonly IScriptingManager _scriptingManager;
|
private readonly IEnumerable<IScriptExpressionEvaluator> _evaluators;
|
||||||
private readonly ICacheManager _cacheManager;
|
|
||||||
|
|
||||||
public RuleManager(IEnumerable<IRuleProvider> ruleProviders, IScriptingManager scriptingManager, ICacheManager cacheManager) {
|
public RuleManager(IEnumerable<IRuleProvider> ruleProviders, IEnumerable<IScriptExpressionEvaluator> evaluators) {
|
||||||
_ruleProviders = ruleProviders;
|
_ruleProviders = ruleProviders;
|
||||||
_scriptingManager = scriptingManager;
|
_evaluators = evaluators;
|
||||||
_cacheManager = cacheManager;
|
T = NullLocalizer.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Localizer T { get; set; }
|
||||||
|
|
||||||
public bool Matches(string expression) {
|
public bool Matches(string expression) {
|
||||||
object execContextType = _cacheManager.Get("---", ctx => (object)_scriptingManager.ExecuteExpression(@"
|
var evaluator = _evaluators.FirstOrDefault();
|
||||||
class ExecBlock
|
if (evaluator == null) {
|
||||||
def initialize(callbacks)
|
throw new OrchardException(T("There are currently not scripting engine enabled"));
|
||||||
@callbacks = callbacks
|
|
||||||
end
|
|
||||||
def method_missing(name, *args, &block)
|
|
||||||
@callbacks.send(name, args, &block);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class ExecContext
|
|
||||||
class << self
|
|
||||||
def alloc(thing)
|
|
||||||
instance_eval 'self.new {' + thing + '}'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
def initialize(&block)
|
|
||||||
@block = block
|
|
||||||
end
|
|
||||||
def evaluate(callbacks)
|
|
||||||
ExecBlock.new(callbacks).instance_eval(&@block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ExecContext
|
|
||||||
"));
|
|
||||||
var ops = _cacheManager.Get("----", ctx => (ObjectOperations)_scriptingManager.ExecuteOperation(x => x));
|
|
||||||
object execContext = _cacheManager.Get(expression, ctx => (object)ops.InvokeMember(execContextType, "alloc", expression));
|
|
||||||
dynamic result = ops.InvokeMember(execContext, "evaluate", new CallbackApi(this));
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CallbackApi {
|
var result = evaluator.Evaluate(expression, new List<IGlobalMethodProvider> { new GlobalMethodProvider(this) });
|
||||||
|
if (!(result is bool)) {
|
||||||
|
throw new OrchardException(T("Expression is not a boolean value"));
|
||||||
|
}
|
||||||
|
return (bool)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GlobalMethodProvider : IGlobalMethodProvider {
|
||||||
private readonly RuleManager _ruleManager;
|
private readonly RuleManager _ruleManager;
|
||||||
|
|
||||||
public CallbackApi(RuleManager ruleManager) {
|
public GlobalMethodProvider(RuleManager ruleManager) {
|
||||||
_ruleManager = ruleManager;
|
_ruleManager = ruleManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object send(string name, IList<object> args) {
|
public void Process(GlobalMethodContext context) {
|
||||||
return _ruleManager.Evaluate(name, args);
|
var ruleContext = new RuleContext {
|
||||||
}
|
FunctionName = context.FunctionName,
|
||||||
}
|
Arguments = context.Arguments.ToArray(),
|
||||||
|
Result = context.Result
|
||||||
|
};
|
||||||
|
|
||||||
private object Evaluate(string name, IList<object> args) {
|
foreach(var ruleProvider in _ruleManager._ruleProviders) {
|
||||||
RuleContext ruleContext = new RuleContext { FunctionName = name, Arguments = args.ToArray() };
|
|
||||||
|
|
||||||
foreach (var ruleProvider in _ruleProviders) {
|
|
||||||
ruleProvider.Process(ruleContext);
|
ruleProvider.Process(ruleContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ruleContext.Result;
|
context.Result = ruleContext.Result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user