mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-01-21 18:49:41 +08:00
Further embedding of Ruby as implementation detail
Interfaces themselves as language agnostic --HG-- branch : dev extra : rebase_source : d15b587bafec98d49b322ba2dd8ad0f493798563
This commit is contained in:
@@ -86,8 +86,6 @@ namespace Orchard.Core.Tests.Body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Thing : ContentPart {
|
public class Thing : ContentPart {
|
||||||
public int Id { get { return ContentItem.Id; } }
|
|
||||||
|
|
||||||
public string Text {
|
public string Text {
|
||||||
get { return this.As<BodyPart>().Text; }
|
get { return this.As<BodyPart>().Text; }
|
||||||
set { this.As<BodyPart>().Text = value; }
|
set { this.As<BodyPart>().Text = value; }
|
||||||
|
|||||||
@@ -208,8 +208,6 @@ namespace Orchard.Core.Tests.Routable.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Thing : ContentPart {
|
public class Thing : ContentPart {
|
||||||
public int Id { get { return ContentItem.Id; } }
|
|
||||||
|
|
||||||
public string Title {
|
public string Title {
|
||||||
get { return this.As<RoutePart>().Title; }
|
get { return this.As<RoutePart>().Title; }
|
||||||
set { this.As<RoutePart>().Title = value; }
|
set { this.As<RoutePart>().Title = value; }
|
||||||
@@ -232,8 +230,6 @@ namespace Orchard.Core.Tests.Routable.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Stuff : ContentPart {
|
public class Stuff : ContentPart {
|
||||||
public int Id { get { return ContentItem.Id; } }
|
|
||||||
|
|
||||||
public string Title {
|
public string Title {
|
||||||
get { return this.As<RoutePart>().Title; }
|
get { return this.As<RoutePart>().Title; }
|
||||||
set { this.As<RoutePart>().Title = value; }
|
set { this.As<RoutePart>().Title = value; }
|
||||||
|
|||||||
@@ -36,11 +36,12 @@ namespace Orchard.Tests.Scripting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void GetRubyEngineReturnsAWorkingRubyEngine() {
|
public void CreateScopeReturnsWorkingScope() {
|
||||||
var ruby = _scriptingRuntime.GetRubyEngine();
|
var scope = _scriptingRuntime.CreateScope();
|
||||||
|
|
||||||
Assert.IsNotNull(ruby);
|
Assert.IsNotNull(scope);
|
||||||
Assert.That(ruby.Execute("21 + 21"), Is.EqualTo(42));
|
scope.SetVariable("alpha", 42);
|
||||||
|
Assert.That(scope.GetVariable("alpha"), Is.EqualTo(42));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -52,7 +53,7 @@ namespace Orchard.Tests.Scripting {
|
|||||||
[Test]
|
[Test]
|
||||||
public void ScriptingManagerCanEvalExpression() {
|
public void ScriptingManagerCanEvalExpression() {
|
||||||
_scriptingManager.SetVariable("foo", 21);
|
_scriptingManager.SetVariable("foo", 21);
|
||||||
Assert.That(_scriptingManager.Eval("foo + 21"), Is.EqualTo(42));
|
Assert.That(_scriptingManager.ExecuteExpression("foo + 21"), Is.EqualTo(42));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -63,8 +64,8 @@ namespace Orchard.Tests.Scripting {
|
|||||||
scriptManager1.SetVariable("foo", 1);
|
scriptManager1.SetVariable("foo", 1);
|
||||||
scriptManager2.SetVariable("foo", 2);
|
scriptManager2.SetVariable("foo", 2);
|
||||||
|
|
||||||
var result1 = scriptManager1.Eval("3 + foo");
|
var result1 = scriptManager1.ExecuteExpression("3 + foo");
|
||||||
var result2 = scriptManager2.Eval("3 + foo");
|
var result2 = scriptManager2.ExecuteExpression("3 + foo");
|
||||||
|
|
||||||
Assert.That(result1, Is.EqualTo(4));
|
Assert.That(result1, Is.EqualTo(4));
|
||||||
Assert.That(result2, Is.EqualTo(5));
|
Assert.That(result2, Is.EqualTo(5));
|
||||||
@@ -75,23 +76,15 @@ namespace Orchard.Tests.Scripting {
|
|||||||
var targetPath = Path.Combine(_tempFolderName, "SampleMethodDefinition.rb");
|
var targetPath = Path.Combine(_tempFolderName, "SampleMethodDefinition.rb");
|
||||||
File.WriteAllText(targetPath, "def f\r\nreturn 32\r\nend\r\n");
|
File.WriteAllText(targetPath, "def f\r\nreturn 32\r\nend\r\n");
|
||||||
_scriptingManager.ExecuteFile(targetPath);
|
_scriptingManager.ExecuteFile(targetPath);
|
||||||
Assert.That(_scriptingManager.Eval("f / 4"), Is.EqualTo(8));
|
Assert.That(_scriptingManager.ExecuteExpression("f / 4"), Is.EqualTo(8));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GlobalObjectCanBeDynamic() {
|
|
||||||
dynamic global = new Clay(new PropBehavior());
|
|
||||||
_scriptingManager.SetScriptingScope(_scriptingRuntime.GetRubyEngine().CreateScope((IDynamicMetaObjectProvider)global));
|
|
||||||
|
|
||||||
global.foo = 5;
|
|
||||||
Assert.That(_scriptingManager.Eval("3 + foo"), Is.EqualTo(8));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void CanDeclareCallbackOnGlobalMethod() {
|
public void CanDeclareCallbackOnGlobalMethod() {
|
||||||
_scriptingManager.SetVariable("x", new Clay(new ReturnMethodNameLengthBehavior()));
|
_scriptingManager.SetVariable("x", new Clay(new ReturnMethodNameLengthBehavior()));
|
||||||
|
|
||||||
Assert.That(_scriptingManager.Eval("3 + x.foo()"), Is.EqualTo(6));
|
Assert.That(_scriptingManager.ExecuteExpression("3 + x.foo()"), Is.EqualTo(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +102,7 @@ namespace Orchard.Tests.Scripting {
|
|||||||
_scriptingManager.ExecuteFile(targetPath);
|
_scriptingManager.ExecuteFile(targetPath);
|
||||||
_scriptingManager.SetVariable("callbacks", new CallbackApi());
|
_scriptingManager.SetVariable("callbacks", new CallbackApi());
|
||||||
|
|
||||||
Assert.That(_scriptingManager.Eval("execute { 1 + hello + world('yep') }"), Is.EqualTo(11));
|
Assert.That(_scriptingManager.ExecuteExpression("execute { 1 + hello + world('yep') }"), Is.EqualTo(11));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CallbackApi {
|
public class CallbackApi {
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ namespace Orchard.Core.Localization.Models {
|
|||||||
public LazyField<CultureRecord> CultureField { get { return _culture; } }
|
public LazyField<CultureRecord> CultureField { get { return _culture; } }
|
||||||
public LazyField<IContent> MasterContentItemField { get { return _masterContentItem; } }
|
public LazyField<IContent> MasterContentItemField { get { return _masterContentItem; } }
|
||||||
|
|
||||||
[HiddenInput(DisplayValue = false)]
|
|
||||||
public int Id { get { return ContentItem.Id; } }
|
|
||||||
|
|
||||||
public CultureRecord Culture {
|
public CultureRecord Culture {
|
||||||
get { return _culture.Value; }
|
get { return _culture.Value; }
|
||||||
set { _culture.Value = value; }
|
set { _culture.Value = value; }
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ using Orchard.ContentManagement;
|
|||||||
|
|
||||||
namespace Orchard.Core.Navigation.Models {
|
namespace Orchard.Core.Navigation.Models {
|
||||||
public class MenuItemPart : ContentPart<MenuItemPartRecord> {
|
public class MenuItemPart : ContentPart<MenuItemPartRecord> {
|
||||||
[HiddenInput(DisplayValue = false)]
|
|
||||||
public int Id { get { return ContentItem.Id; } }
|
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string Url {
|
public string Url {
|
||||||
get { return Record.Url; }
|
get { return Record.Url; }
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ using Orchard.ContentManagement;
|
|||||||
|
|
||||||
namespace Orchard.Core.Navigation.Models {
|
namespace Orchard.Core.Navigation.Models {
|
||||||
public class MenuPart : ContentPart<MenuPartRecord> {
|
public class MenuPart : ContentPart<MenuPartRecord> {
|
||||||
[HiddenInput(DisplayValue = false)]
|
|
||||||
public int Id { get { return ContentItem.Id; } }
|
|
||||||
|
|
||||||
public bool OnMainMenu {
|
public bool OnMainMenu {
|
||||||
get { return Record.OnMainMenu; }
|
get { return Record.OnMainMenu; }
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ using Orchard.Core.Routable.Models;
|
|||||||
|
|
||||||
namespace Orchard.Blogs.Models {
|
namespace Orchard.Blogs.Models {
|
||||||
public class BlogPart : ContentPart<BlogPartRecord> {
|
public class BlogPart : ContentPart<BlogPartRecord> {
|
||||||
[HiddenInput(DisplayValue = false)]
|
|
||||||
public int Id { get { return ContentItem.Id; } }
|
|
||||||
|
|
||||||
public string Name {
|
public string Name {
|
||||||
get { return this.As<RoutePart>().Title; }
|
get { return this.As<RoutePart>().Title; }
|
||||||
set { this.As<RoutePart>().Title = value; }
|
set { this.As<RoutePart>().Title = value; }
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Orchard.Widgets.RuleEngine {
|
|||||||
|
|
||||||
public bool Matches(string expression) {
|
public bool Matches(string expression) {
|
||||||
_scriptingManager.SetVariable("callbacks", new CallbackApi(this));
|
_scriptingManager.SetVariable("callbacks", new CallbackApi(this));
|
||||||
dynamic execContext = _scriptingManager.Eval(@"
|
dynamic execContext = _scriptingManager.ExecuteExpression(@"
|
||||||
class ExecContext
|
class ExecContext
|
||||||
def initialize(callbacks)
|
def initialize(callbacks)
|
||||||
@callbacks = callbacks;
|
@callbacks = callbacks;
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
using Microsoft.Scripting.Hosting;
|
namespace Orchard.Scripting {
|
||||||
|
|
||||||
namespace Orchard.Scripting {
|
|
||||||
public interface IScriptingManager : IDependency {
|
public interface IScriptingManager : IDependency {
|
||||||
dynamic GetVariable(string name);
|
dynamic GetVariable(string name);
|
||||||
void SetVariable(string name, object value);
|
void SetVariable(string name, object value);
|
||||||
dynamic Eval(string expression);
|
dynamic ExecuteExpression(string expression);
|
||||||
void ExecuteFile(string fileName);
|
void ExecuteFile(string fileName);
|
||||||
void SetScriptingScope(ScriptScope scriptScope);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace Orchard.Scripting {
|
namespace Orchard.Scripting {
|
||||||
public interface IScriptingRuntime : ISingletonDependency {
|
public interface IScriptingRuntime : ISingletonDependency {
|
||||||
ScriptEngine GetRubyEngine();
|
ScriptScope CreateScope();
|
||||||
|
dynamic ExecuteExpression(string expression, ScriptScope scope);
|
||||||
|
void ExecuteFile(string fileName, ScriptScope scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,31 @@
|
|||||||
using Microsoft.Scripting.Hosting;
|
using System;
|
||||||
|
using Microsoft.Scripting.Hosting;
|
||||||
|
|
||||||
namespace Orchard.Scripting {
|
namespace Orchard.Scripting {
|
||||||
public class ScriptingManager : IScriptingManager {
|
public class ScriptingManager : IScriptingManager {
|
||||||
private readonly IScriptingRuntime _scriptingRuntime;
|
private readonly IScriptingRuntime _scriptingRuntime;
|
||||||
private ScriptScope _scriptingScope;
|
private Lazy<ScriptScope> _scope;
|
||||||
|
|
||||||
public ScriptingManager(IScriptingRuntime scriptingRuntime) {
|
public ScriptingManager(IScriptingRuntime scriptingRuntime) {
|
||||||
_scriptingRuntime = scriptingRuntime;
|
_scriptingRuntime = scriptingRuntime;
|
||||||
_scriptingScope = _scriptingRuntime.GetRubyEngine().CreateScope();
|
_scope = new Lazy<ScriptScope>(()=>_scriptingRuntime.CreateScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IScriptingContext Members
|
|
||||||
|
|
||||||
public dynamic GetVariable(string name) {
|
public dynamic GetVariable(string name) {
|
||||||
return _scriptingScope.GetVariable(name);
|
return _scope.Value.GetVariable(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariable(string name, object value) {
|
public void SetVariable(string name, object value) {
|
||||||
_scriptingScope.SetVariable(name, value);
|
_scope.Value.SetVariable(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dynamic Eval(string expression) {
|
public dynamic ExecuteExpression(string expression) {
|
||||||
var script = _scriptingRuntime.GetRubyEngine().CreateScriptSourceFromString(expression);
|
return _scriptingRuntime.ExecuteExpression(expression, _scope.Value);
|
||||||
return script.Execute(_scriptingScope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExecuteFile(string fileName) {
|
public void ExecuteFile(string fileName) {
|
||||||
_scriptingRuntime.GetRubyEngine().ExecuteFile(fileName, _scriptingScope);
|
_scriptingRuntime.ExecuteFile(fileName, _scope.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetScriptingScope(ScriptScope scriptScope) {
|
|
||||||
_scriptingScope = scriptScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,34 @@ using Microsoft.Scripting.Hosting;
|
|||||||
|
|
||||||
namespace Orchard.Scripting {
|
namespace Orchard.Scripting {
|
||||||
public class ScriptingRuntime : IScriptingRuntime {
|
public class ScriptingRuntime : IScriptingRuntime {
|
||||||
|
private readonly LanguageSetup _defaultLanguageSetup;
|
||||||
private readonly ScriptRuntime _scriptingRuntime;
|
private readonly ScriptRuntime _scriptingRuntime;
|
||||||
|
|
||||||
public ScriptingRuntime() {
|
public ScriptingRuntime() {
|
||||||
|
_defaultLanguageSetup = Ruby.CreateRubySetup();
|
||||||
|
|
||||||
var setup = new ScriptRuntimeSetup();
|
var setup = new ScriptRuntimeSetup();
|
||||||
setup.LanguageSetups.Add(Ruby.CreateRubySetup());
|
setup.LanguageSetups.Add(_defaultLanguageSetup);
|
||||||
_scriptingRuntime = new ScriptRuntime(setup);
|
_scriptingRuntime = new ScriptRuntime(setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScriptEngine GetRubyEngine() {
|
ScriptEngine GetDefaultEngine() {
|
||||||
return _scriptingRuntime.GetEngine("ruby");
|
return _scriptingRuntime.GetEngineByTypeName(_defaultLanguageSetup.TypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScriptScope CreateScope() {
|
||||||
|
return _scriptingRuntime.CreateScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic ExecuteExpression(string expression, ScriptScope scope) {
|
||||||
|
var engine = GetDefaultEngine();
|
||||||
|
var source = engine.CreateScriptSourceFromString(expression);
|
||||||
|
return source.Execute(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExecuteFile(string fileName, ScriptScope scope) {
|
||||||
|
var engine = GetDefaultEngine();
|
||||||
|
engine.ExecuteFile(fileName, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ namespace Orchard.Security {
|
|||||||
/// Interface provided by the "User" model.
|
/// Interface provided by the "User" model.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IUser : IContent {
|
public interface IUser : IContent {
|
||||||
int Id { get; }
|
|
||||||
string UserName { get; }
|
string UserName { get; }
|
||||||
string Email { get; }
|
string Email { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user