diff --git a/src/Orchard.Tests/DisplayManagement/DefaultShapeTableFactoryTests.cs b/src/Orchard.Tests/DisplayManagement/DefaultShapeTableFactoryTests.cs index 8760c7fc1..dba922a7a 100644 --- a/src/Orchard.Tests/DisplayManagement/DefaultShapeTableFactoryTests.cs +++ b/src/Orchard.Tests/DisplayManagement/DefaultShapeTableFactoryTests.cs @@ -19,14 +19,14 @@ namespace Orchard.Tests.DisplayManagement { [Test] public void ShapeTableRecognizesMethodNames() { - var stf = CreateShapeTableFactory(cfg => cfg.RegisterType().As()); + var stf = CreateShapeTableFactory(cfg => cfg.RegisterType().As()); var shapeTable = stf.CreateShapeTable(); Assert.That(shapeTable.Entries.Count(), Is.EqualTo(2)); Assert.That(shapeTable.Entries.ContainsKey("Pager")); Assert.That(shapeTable.Entries.ContainsKey("Email")); } - public class Test : IShapeProvider { + public class Test : IShapeDriver { public void Pager() { } diff --git a/src/Orchard.Tests/DisplayManagement/DisplayHelperTests.cs b/src/Orchard.Tests/DisplayManagement/DisplayHelperTests.cs index fd3dd37e5..4187bb2a1 100644 --- a/src/Orchard.Tests/DisplayManagement/DisplayHelperTests.cs +++ b/src/Orchard.Tests/DisplayManagement/DisplayHelperTests.cs @@ -8,6 +8,7 @@ using ClaySharp.Implementation; using Moq; using NUnit.Framework; using Orchard.DisplayManagement; +using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Shapes; namespace Orchard.Tests.DisplayManagement { @@ -18,14 +19,14 @@ namespace Orchard.Tests.DisplayManagement { var viewContext = new ViewContext(); var displayManager = new Mock(); - var shapeFactory = new Mock(); + var shapeFactory = new Mock(); var displayHelperFactory = new DisplayHelperFactory(displayManager.Object, shapeFactory.Object); - var displayHelper = displayHelperFactory.CreateDisplayHelper(viewContext, null); + var displayHelper = displayHelperFactory.CreateHelper(viewContext, null); displayHelper.Invoke("Pager", ArgsUtility.Positional(1, 2, 3, 4)); - shapeFactory.Verify(sf=>sf.Build("Pager", It.IsAny>())); + shapeFactory.Verify(sf => sf.Create("Pager", It.IsAny>())); //displayManager.Verify(dm => dm.Execute(It.IsAny(), viewContext, null)); } [Test] @@ -33,14 +34,14 @@ namespace Orchard.Tests.DisplayManagement { var viewContext = new ViewContext(); var displayManager = new Mock(); - var shapeFactory = new Mock(); + var shapeFactory = new Mock(); var displayHelperFactory = new DisplayHelperFactory(displayManager.Object, shapeFactory.Object); - var display = (dynamic)displayHelperFactory.CreateDisplayHelper(viewContext, null); + var display = (dynamic)displayHelperFactory.CreateHelper(viewContext, null); display.Pager(1, 2, 3, 4); - shapeFactory.Verify(sf => sf.Build("Pager", It.IsAny>())); + shapeFactory.Verify(sf => sf.Create("Pager", It.IsAny>())); //displayManager.Verify(dm => dm.Execute(It.IsAny(), viewContext, null)); } @@ -51,10 +52,10 @@ namespace Orchard.Tests.DisplayManagement { var viewContext = new ViewContext(); var displayManager = new Mock(); - var shapeFactory = new Mock(); + var shapeFactory = new Mock(); var displayHelperFactory = new DisplayHelperFactory(displayManager.Object, shapeFactory.Object); - var display = (dynamic)displayHelperFactory.CreateDisplayHelper(viewContext, null); + var display = (dynamic)displayHelperFactory.CreateHelper(viewContext, null); var outline = new Shape { Attributes = new ShapeAttributes { Type = "Outline" } }; display(outline); diff --git a/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs b/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs index c19bdfd6f..9a9dd9995 100644 --- a/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs +++ b/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs @@ -15,23 +15,23 @@ namespace Orchard.Tests.DisplayManagement { [SetUp] public void Init() { var builder = new ContainerBuilder(); - builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); } [Test] public void ShapeHasAttributesType() { - var factory = _container.Resolve(); - dynamic foo = factory.Build("Foo", ArgsUtility.Empty()); + var factory = _container.Resolve(); + dynamic foo = factory.Create("Foo", ArgsUtility.Empty()); ShapeAttributes attributes = foo.Attributes; Assert.That(attributes.Type, Is.EqualTo("Foo")); } [Test] public void CreateShapeWithNamedArguments() { - var factory = _container.Resolve(); - var foo = factory.Build("Foo", ArgsUtility.Named(new { one = 1, two = "dos" })); + var factory = _container.Resolve(); + var foo = factory.Create("Foo", ArgsUtility.Named(new { one = 1, two = "dos" })); } } } diff --git a/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs b/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs index 1475e206a..d3f7e5bf0 100644 --- a/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs +++ b/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs @@ -5,6 +5,7 @@ using System.Text; using Autofac; using NUnit.Framework; using Orchard.DisplayManagement; +using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Shapes; namespace Orchard.Tests.DisplayManagement { @@ -16,14 +17,14 @@ namespace Orchard.Tests.DisplayManagement { public void Init() { var builder = new ContainerBuilder(); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); } [Test] public void CreatingNewShapeTypeByName() { - dynamic shape = _container.Resolve().CreateShapeHelper(); + dynamic shape = _container.Resolve().CreateHelper(); var alpha = shape.Alpha(); @@ -32,7 +33,7 @@ namespace Orchard.Tests.DisplayManagement { [Test] public void CreatingShapeWithAdditionalNamedParameters() { - dynamic shape = _container.Resolve().CreateShapeHelper(); + dynamic shape = _container.Resolve().CreateHelper(); var alpha = shape.Alpha(one: 1, two: "dos"); @@ -43,7 +44,7 @@ namespace Orchard.Tests.DisplayManagement { [Test] public void WithPropertyBearingObjectInsteadOfNamedParameters() { - dynamic shape = _container.Resolve().CreateShapeHelper(); + dynamic shape = _container.Resolve().CreateHelper(); var alpha = shape.Alpha(new { one = 1, two = "dos" }); diff --git a/src/Orchard.Tests/DisplayManagement/SubsystemTests.cs b/src/Orchard.Tests/DisplayManagement/SubsystemTests.cs index 9fa0d7762..8bae3877d 100644 --- a/src/Orchard.Tests/DisplayManagement/SubsystemTests.cs +++ b/src/Orchard.Tests/DisplayManagement/SubsystemTests.cs @@ -7,6 +7,7 @@ using System.Web.Mvc; using Autofac; using NUnit.Framework; using Orchard.DisplayManagement; +using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Secondary; using Orchard.DisplayManagement.Shapes; @@ -19,15 +20,15 @@ namespace Orchard.Tests.DisplayManagement { public void Init() { var builder = new ContainerBuilder(); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); } - public class SimpleShapes : IShapeProvider { + public class SimpleShapes : IShapeDriver { public IHtmlString Something() { return new HtmlString("
"); } @@ -41,9 +42,9 @@ namespace Orchard.Tests.DisplayManagement { public void RenderingSomething() { var viewContext = new ViewContext(); - dynamic Display = _container.Resolve().CreateDisplayHelper(viewContext, null); + dynamic Display = _container.Resolve().CreateHelper(viewContext, null); - dynamic New = _container.Resolve().CreateShapeHelper(); + dynamic New = _container.Resolve().CreateHelper(); var result1 = Display.Something(); var result2 = ((DisplayHelper)Display).ShapeExecute((Shape)New.Pager()); diff --git a/src/Orchard.Web/Modules/Orchard.DevTools/Controllers/HomeController.cs b/src/Orchard.Web/Modules/Orchard.DevTools/Controllers/HomeController.cs index 65276414a..f510ff119 100644 --- a/src/Orchard.Web/Modules/Orchard.DevTools/Controllers/HomeController.cs +++ b/src/Orchard.Web/Modules/Orchard.DevTools/Controllers/HomeController.cs @@ -1,5 +1,6 @@ using System; using System.Dynamic; +using System.Web; using System.Web.Mvc; using Orchard.DevTools.Models; using Orchard.DisplayManagement; @@ -8,6 +9,7 @@ using Orchard.Mvc.ViewModels; using Orchard.Themes; using Orchard.UI.Notify; using Orchard.UI.Admin; +using Orchard.UI.Zones; namespace Orchard.DevTools.Controllers { [Themed] @@ -18,7 +20,7 @@ namespace Orchard.DevTools.Controllers { public HomeController(INotifier notifier, IShapeHelperFactory shapeHelperFactory) { _notifier = notifier; T = NullLocalizer.Instance; - New = shapeHelperFactory.CreateShapeHelper(); + New = shapeHelperFactory.CreateHelper(); } dynamic New { get; set; } @@ -52,16 +54,26 @@ namespace Orchard.DevTools.Controllers { return View("Simple", new Simple { Title = "This is not themed", Quantity = 5 }); } + + public ActionResult UsingShapes() { + ViewModel.Page = New.Page() - .Main(New.Zone(typeof(Array), Name: "Main")) - .Messages(New.Zone(typeof(Array), Name: "Main")) - .Sidebar(New.Zone(typeof(Array), Name: "Main")); + .Main(New.Zone(typeof (Array), Name: "Main")) + .Messages(New.Zone(typeof (Array), Name: "Messages")) + .Sidebar(New.Zone(typeof (Array), Name: "Sidebar")); + + ViewModel.Page.Add("Messages:5", New.Message(Content: T("This is a test"), Severity: "Really bad!!!")); ViewModel.Page.Messages.Add( New.Message(Content: T("This is a test"), Severity: "Really bad!!!")); - var model = New.Explosion(Height: 100, Width: 200); + var model = New.Message( + Content: New.Explosion(Height: 100, Width: 200), + Severity: "Meh"); + + ViewModel.Page.Messages.Add(new HtmlString("
abuse
")); + ViewModel.Page.Messages.Add("
encoded
"); return View("UsingShapes", model); } @@ -70,7 +82,5 @@ namespace Orchard.DevTools.Controllers { return view.Model.Box.Title; } } - public class MyViewModel { - public dynamic Box { get; set; } - } + } diff --git a/src/Orchard.Web/Modules/Orchard.DevTools/Shapes.cs b/src/Orchard.Web/Modules/Orchard.DevTools/Shapes.cs index 8303b9835..9a9063318 100644 --- a/src/Orchard.Web/Modules/Orchard.DevTools/Shapes.cs +++ b/src/Orchard.Web/Modules/Orchard.DevTools/Shapes.cs @@ -6,13 +6,13 @@ using System.Web.Mvc; using Orchard.DisplayManagement; namespace Orchard.DevTools { - public class Shapes : IShapeProvider { + public class Shapes : IShapeDriver { public IHtmlString Title(dynamic text) { return new HtmlString("

" + text + "

"); } - public IHtmlString Explosion(int Height, int Width) { - return new HtmlString(string.Format("
Boom {0}x{1}
", Height, Width)); + public IHtmlString Explosion(int? Height, int? Width) { + return new HtmlString(string.Format("Boom {0}x{1}", Height, Width)); } public IHtmlString Page(dynamic Display, dynamic Shape) { @@ -29,7 +29,7 @@ namespace Orchard.DevTools { } public IHtmlString Message(dynamic Display, object Content, string Severity) { - return Display(Severity, ": ", Content); + return Display(new HtmlString("

"), Severity ?? "Neutral", ": ", Content, new HtmlString("

")); } private static IHtmlString Smash(IEnumerable contents) { diff --git a/src/Orchard.Web/Modules/Orchard.DevTools/Views/Home/UsingShapes.cshtml b/src/Orchard.Web/Modules/Orchard.DevTools/Views/Home/UsingShapes.cshtml index d53b6299c..d71563273 100644 --- a/src/Orchard.Web/Modules/Orchard.DevTools/Views/Home/UsingShapes.cshtml +++ b/src/Orchard.Web/Modules/Orchard.DevTools/Views/Home/UsingShapes.cshtml @@ -1,8 +1,14 @@ 
- @Display.Title(text:"This is everything") - @Display(Model) +a @Display.Title(text:"This is everything") +b @Display(Model) - @Display(View.Page) +c @Display(View.Page) + +d @Display.Message(Content:"Madness!!!") + +e @Display.Explosion(Width:40) + +f @Display.Message(Content: @Display.Explosion(Height:10,Width:15))
diff --git a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs index a3a53de14..b017a90f1 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs @@ -12,6 +12,7 @@ using Orchard.Data.Migration.Interpreters; using Orchard.Data.Providers; using Orchard.Data.Migration; using Orchard.DisplayManagement; +using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Secondary; using Orchard.DisplayManagement.Shapes; using Orchard.Environment.Extensions; @@ -64,7 +65,7 @@ namespace Orchard.Setup { // in progress - adding services for display/shape support in setup builder.RegisterType().As(); builder.RegisterType().As(); - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); } diff --git a/src/Orchard/DisplayManagement/HelperFactories/IDisplayHelperFactory.cs b/src/Orchard/DisplayManagement/HelperFactories/IDisplayHelperFactory.cs deleted file mode 100644 index f178e5f96..000000000 --- a/src/Orchard/DisplayManagement/HelperFactories/IDisplayHelperFactory.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System.Web.Mvc; - -namespace Orchard.DisplayManagement { - public interface IDisplayHelperFactory : IDependency { - DisplayHelper CreateDisplayHelper(ViewContext viewContext, IViewDataContainer viewDataContainer); - } -} \ No newline at end of file diff --git a/src/Orchard/DisplayManagement/HelperFactories/ShapeHelperFactory.cs b/src/Orchard/DisplayManagement/HelperFactories/ShapeHelperFactory.cs deleted file mode 100644 index 0e5f61757..000000000 --- a/src/Orchard/DisplayManagement/HelperFactories/ShapeHelperFactory.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using ClaySharp; -using Orchard.DisplayManagement.Shapes; - -namespace Orchard.DisplayManagement { - public class ShapeHelperFactory : IShapeHelperFactory { - static private readonly ShapeHelperBehavior[] _behaviors = new[] { new ShapeHelperBehavior() }; - private readonly IShapeBuilder _shapeBuilder; - - public ShapeHelperFactory(IShapeBuilder shapeBuilder) { - _shapeBuilder = shapeBuilder; - } - - public ShapeHelper CreateShapeHelper() { - return (ShapeHelper)ClayActivator.CreateInstance( - _behaviors, - _shapeBuilder); - } - - class ShapeHelperBehavior : ClayBehavior { - public override object InvokeMember(Func proceed, object target, string name, INamedEnumerable args) { - return ((ShapeHelper)target).CreateShapeType(name, args); - } - } - - } -} diff --git a/src/Orchard/DisplayManagement/IDisplayHelperFactory.cs b/src/Orchard/DisplayManagement/IDisplayHelperFactory.cs new file mode 100644 index 000000000..00d10f904 --- /dev/null +++ b/src/Orchard/DisplayManagement/IDisplayHelperFactory.cs @@ -0,0 +1,11 @@ +using System.Runtime.CompilerServices; +using System.Web.Mvc; + +namespace Orchard.DisplayManagement { + /// + /// Used to create a dynamic, contextualized Display object to dispatch shape rendering + /// + public interface IDisplayHelperFactory : IDependency { + dynamic CreateHelper(ViewContext viewContext, IViewDataContainer viewDataContainer); + } +} \ No newline at end of file diff --git a/src/Orchard/DisplayManagement/IDisplayManager.cs b/src/Orchard/DisplayManagement/IDisplayManager.cs deleted file mode 100644 index 003112b49..000000000 --- a/src/Orchard/DisplayManagement/IDisplayManager.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Web; -using System.Web.Mvc; -using ClaySharp; -using Orchard.DisplayManagement.Shapes; - -namespace Orchard.DisplayManagement { - public interface IDisplayManager : IDependency { - IHtmlString Execute(DisplayContext context); - } -} diff --git a/src/Orchard/DisplayManagement/IShape.cs b/src/Orchard/DisplayManagement/IShape.cs new file mode 100644 index 000000000..8b19cf297 --- /dev/null +++ b/src/Orchard/DisplayManagement/IShape.cs @@ -0,0 +1,13 @@ +using System.Runtime.CompilerServices; +using Orchard.DisplayManagement.Shapes; + +namespace Orchard.DisplayManagement { + /// + /// Interface present on dynamic shapes. + /// May be used to access attributes in a strongly typed fashion. + /// Note: Anything on this interface is a reserved word for the purpose of shape properties + /// + public interface IShape { + IShapeAttributes Attributes { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard/DisplayManagement/IShapeAttributes.cs b/src/Orchard/DisplayManagement/IShapeAttributes.cs new file mode 100644 index 000000000..6c9507552 --- /dev/null +++ b/src/Orchard/DisplayManagement/IShapeAttributes.cs @@ -0,0 +1,6 @@ +namespace Orchard.DisplayManagement { + public interface IShapeAttributes { + string Type { get; set; } + string Position { get; set; } + } +} diff --git a/src/Orchard/DisplayManagement/IShapeDriver.cs b/src/Orchard/DisplayManagement/IShapeDriver.cs new file mode 100644 index 000000000..239d9eb1f --- /dev/null +++ b/src/Orchard/DisplayManagement/IShapeDriver.cs @@ -0,0 +1,7 @@ +namespace Orchard.DisplayManagement { + /// + /// Base interface for module components which define new shape types and + /// optionally provide default implementation method + /// + public interface IShapeDriver : IDependency{} +} \ No newline at end of file diff --git a/src/Orchard/DisplayManagement/IShapeFactory.cs b/src/Orchard/DisplayManagement/IShapeFactory.cs new file mode 100644 index 000000000..2383544b3 --- /dev/null +++ b/src/Orchard/DisplayManagement/IShapeFactory.cs @@ -0,0 +1,12 @@ +using ClaySharp; +using Orchard.DisplayManagement.Shapes; + +namespace Orchard.DisplayManagement { + /// + /// Service that creates new instances of dynamic shape objects + /// This may be used directly, or through the IShapeHelperFactory. + /// + public interface IShapeFactory : IDependency { + IShape Create(string shapeType, INamedEnumerable parameters); + } +} diff --git a/src/Orchard/DisplayManagement/HelperFactories/IShapeHelperFactory.cs b/src/Orchard/DisplayManagement/IShapeHelperFactory.cs similarity index 70% rename from src/Orchard/DisplayManagement/HelperFactories/IShapeHelperFactory.cs rename to src/Orchard/DisplayManagement/IShapeHelperFactory.cs index 76ab67ebf..10219ee30 100644 --- a/src/Orchard/DisplayManagement/HelperFactories/IShapeHelperFactory.cs +++ b/src/Orchard/DisplayManagement/IShapeHelperFactory.cs @@ -1,5 +1,5 @@ namespace Orchard.DisplayManagement { public interface IShapeHelperFactory : IDependency { - ShapeHelper CreateShapeHelper(); + dynamic CreateHelper(); } } \ No newline at end of file diff --git a/src/Orchard/DisplayManagement/Secondary/DefaultDisplayManager.cs b/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs similarity index 88% rename from src/Orchard/DisplayManagement/Secondary/DefaultDisplayManager.cs rename to src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs index a0dd5c64d..440b9926d 100644 --- a/src/Orchard/DisplayManagement/Secondary/DefaultDisplayManager.cs +++ b/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using System.Web; using System.Web.Mvc; using Microsoft.CSharp.RuntimeBinder; +using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Shapes; using Orchard.Localization; @@ -12,7 +13,12 @@ namespace Orchard.DisplayManagement.Secondary { public class DefaultDisplayManager : IDisplayManager { private readonly IShapeTableFactory _shapeTableFactory; - private static CallSite> _convertAsShapeCallsite; + private static CallSite> _convertAsShapeCallsite = CallSite>.Create( + new ForgivingConvertBinder( + (ConvertBinder)Binder.Convert( + CSharpBinderFlags.ConvertExplicit | CSharpBinderFlags.CheckedContext, + typeof(IShape), + null/*typeof(DefaultDisplayManager)*/))); public DefaultDisplayManager(IShapeTableFactory shapeTableFactory) { _shapeTableFactory = shapeTableFactory; @@ -23,14 +29,6 @@ namespace Orchard.DisplayManagement.Secondary { public IHtmlString Execute(DisplayContext context) { - if (_convertAsShapeCallsite == null) { - _convertAsShapeCallsite = CallSite>.Create( - new ForgivingConvertBinder( - (ConvertBinder)Binder.Convert( - CSharpBinderFlags.ConvertExplicit | CSharpBinderFlags.CheckedContext, - typeof(Shape), - null/*typeof(DefaultDisplayManager)*/))); - } var shape = _convertAsShapeCallsite.Target(_convertAsShapeCallsite, context.Value); // non-shape arguements are returned as a no-op @@ -61,7 +59,7 @@ namespace Orchard.DisplayManagement.Secondary { return new HtmlString(HttpUtility.HtmlEncode(value)); } - private IHtmlString Process(ShapeTable.Entry entry, Shape shape, DisplayContext context) { + private IHtmlString Process(ShapeTable.Entry entry, IShape shape, DisplayContext context) { return CoerceHtmlString(entry.Target(context)); } diff --git a/src/Orchard/DisplayManagement/Shapes/DefaultShapeBuilder.cs b/src/Orchard/DisplayManagement/Implementation/DefaultShapeFactory.cs similarity index 91% rename from src/Orchard/DisplayManagement/Shapes/DefaultShapeBuilder.cs rename to src/Orchard/DisplayManagement/Implementation/DefaultShapeFactory.cs index de4664528..6cd78d1bf 100644 --- a/src/Orchard/DisplayManagement/Shapes/DefaultShapeBuilder.cs +++ b/src/Orchard/DisplayManagement/Implementation/DefaultShapeFactory.cs @@ -3,8 +3,8 @@ using System.Linq; using ClaySharp; namespace Orchard.DisplayManagement.Shapes { - public class DefaultShapeBuilder : IShapeBuilder { - public Shape Build(string shapeType, INamedEnumerable parameters) { + public class DefaultShapeFactory : IShapeFactory { + public IShape Create(string shapeType, INamedEnumerable parameters) { var positional = parameters.Positional; diff --git a/src/Orchard/DisplayManagement/Speculation/DisplayContext.cs b/src/Orchard/DisplayManagement/Implementation/DisplayContext.cs similarity index 100% rename from src/Orchard/DisplayManagement/Speculation/DisplayContext.cs rename to src/Orchard/DisplayManagement/Implementation/DisplayContext.cs diff --git a/src/Orchard/DisplayManagement/DisplayHelper.cs b/src/Orchard/DisplayManagement/Implementation/DisplayHelper.cs similarity index 80% rename from src/Orchard/DisplayManagement/DisplayHelper.cs rename to src/Orchard/DisplayManagement/Implementation/DisplayHelper.cs index c790b0f6f..8f94b7733 100644 --- a/src/Orchard/DisplayManagement/DisplayHelper.cs +++ b/src/Orchard/DisplayManagement/Implementation/DisplayHelper.cs @@ -4,22 +4,27 @@ using System.Linq; using System.Web; using System.Web.Mvc; using ClaySharp; +using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Shapes; namespace Orchard.DisplayManagement { - + /// + /// Refactor: I this doesn't really need to exist, does it? + /// It can all be an aspect of a display helper behavior implementation... + /// Or should this remain a CLR type for clarity? + /// public class DisplayHelper { private readonly IDisplayManager _displayManager; - private readonly IShapeBuilder _shapeBuilder; + private readonly IShapeFactory _shapeFactory; public DisplayHelper( IDisplayManager displayManager, - IShapeBuilder shapeBuilder, + IShapeFactory shapeFactory, ViewContext viewContext, IViewDataContainer viewDataContainer) { _displayManager = displayManager; - _shapeBuilder = shapeBuilder; + _shapeFactory = shapeFactory; ViewContext = viewContext; ViewDataContainer = viewDataContainer; } @@ -60,7 +65,7 @@ namespace Orchard.DisplayManagement { } private object ShapeTypeExecute(string name, INamedEnumerable parameters) { - var shape = _shapeBuilder.Build(name, parameters); + var shape = _shapeFactory.Create(name, parameters); return ShapeExecute(shape); } diff --git a/src/Orchard/DisplayManagement/HelperFactories/DisplayHelperFactory.cs b/src/Orchard/DisplayManagement/Implementation/DisplayHelperFactory.cs similarity index 69% rename from src/Orchard/DisplayManagement/HelperFactories/DisplayHelperFactory.cs rename to src/Orchard/DisplayManagement/Implementation/DisplayHelperFactory.cs index 163b242ca..5936aefd9 100644 --- a/src/Orchard/DisplayManagement/HelperFactories/DisplayHelperFactory.cs +++ b/src/Orchard/DisplayManagement/Implementation/DisplayHelperFactory.cs @@ -1,24 +1,25 @@ using System; using System.Web.Mvc; using ClaySharp; +using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Shapes; namespace Orchard.DisplayManagement { public class DisplayHelperFactory : IDisplayHelperFactory { static private readonly DisplayHelperBehavior[] _behaviors = new[] { new DisplayHelperBehavior() }; private readonly IDisplayManager _displayManager; - private readonly IShapeBuilder _shapeBuilder; + private readonly IShapeFactory _shapeFactory; - public DisplayHelperFactory(IDisplayManager displayManager, IShapeBuilder shapeBuilder) { + public DisplayHelperFactory(IDisplayManager displayManager, IShapeFactory shapeFactory) { _displayManager = displayManager; - _shapeBuilder = shapeBuilder; + _shapeFactory = shapeFactory; } - public DisplayHelper CreateDisplayHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) { - return (DisplayHelper)ClayActivator.CreateInstance( + public dynamic CreateHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) { + return ClayActivator.CreateInstance( _behaviors, _displayManager, - _shapeBuilder, + _shapeFactory, viewContext, viewDataContainer); } diff --git a/src/Orchard/DisplayManagement/Implementation/IDisplayManager.cs b/src/Orchard/DisplayManagement/Implementation/IDisplayManager.cs new file mode 100644 index 000000000..4af4868cc --- /dev/null +++ b/src/Orchard/DisplayManagement/Implementation/IDisplayManager.cs @@ -0,0 +1,12 @@ +using System.Web; + +namespace Orchard.DisplayManagement.Implementation { + /// + /// Coordinates the rendering of shapes. + /// This interface isn't used directly - instead you would call through a + /// DisplayHelper created by the IDisplayHelperFactory interface + /// + public interface IDisplayManager : IDependency { + IHtmlString Execute(DisplayContext context); + } +} diff --git a/src/Orchard/DisplayManagement/Implementation/ShapeHelper.cs b/src/Orchard/DisplayManagement/Implementation/ShapeHelper.cs new file mode 100644 index 000000000..24470e2f6 --- /dev/null +++ b/src/Orchard/DisplayManagement/Implementation/ShapeHelper.cs @@ -0,0 +1,15 @@ +using ClaySharp; + +namespace Orchard.DisplayManagement.Implementation { + public class ShapeHelper { + private readonly IShapeFactory _shapeFactory; + + public ShapeHelper(IShapeFactory shapeFactory) { + _shapeFactory = shapeFactory; + } + + public IShape CreateShapeType(string shapeType, INamedEnumerable parameters) { + return _shapeFactory.Create(shapeType, parameters); + } + } +} diff --git a/src/Orchard/DisplayManagement/Implementation/ShapeHelperFactory.cs b/src/Orchard/DisplayManagement/Implementation/ShapeHelperFactory.cs new file mode 100644 index 000000000..cca8871d6 --- /dev/null +++ b/src/Orchard/DisplayManagement/Implementation/ShapeHelperFactory.cs @@ -0,0 +1,26 @@ +using System; +using ClaySharp; + +namespace Orchard.DisplayManagement.Implementation { + public class ShapeHelperFactory : IShapeHelperFactory { + static private readonly ShapeHelperBehavior[] _behaviors = new[] { new ShapeHelperBehavior() }; + private readonly IShapeFactory _shapeFactory; + + public ShapeHelperFactory(IShapeFactory shapeFactory) { + _shapeFactory = shapeFactory; + } + + public dynamic CreateHelper() { + return ClayActivator.CreateInstance( + _behaviors, + _shapeFactory); + } + + class ShapeHelperBehavior : ClayBehavior { + public override object InvokeMember(Func proceed, object target, string name, INamedEnumerable args) { + return ((ShapeHelper)target).CreateShapeType(name, args); + } + } + + } +} diff --git a/src/Orchard/DisplayManagement/ShapeHelper.cs b/src/Orchard/DisplayManagement/ShapeHelper.cs deleted file mode 100644 index 1bc8af559..000000000 --- a/src/Orchard/DisplayManagement/ShapeHelper.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using ClaySharp; -using Orchard.DisplayManagement.Shapes; - -namespace Orchard.DisplayManagement { - public class ShapeHelper { - private readonly IShapeBuilder _shapeBuilder; - - public ShapeHelper(IShapeBuilder shapeBuilder) { - _shapeBuilder = shapeBuilder; - } - - public Shape CreateShapeType(string shapeType, INamedEnumerable parameters) { - return _shapeBuilder.Build(shapeType, parameters); - } - } -} diff --git a/src/Orchard/DisplayManagement/Shapes/IShapeBuilder.cs b/src/Orchard/DisplayManagement/Shapes/IShapeBuilder.cs deleted file mode 100644 index 9120225f5..000000000 --- a/src/Orchard/DisplayManagement/Shapes/IShapeBuilder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using ClaySharp; - -namespace Orchard.DisplayManagement.Shapes { - public interface IShapeBuilder : IDependency { - Shape Build(string shapeType, INamedEnumerable parameters); - } -} diff --git a/src/Orchard/DisplayManagement/Shapes/Shape.cs b/src/Orchard/DisplayManagement/Shapes/Shape.cs index 822d352ca..169e30aaa 100644 --- a/src/Orchard/DisplayManagement/Shapes/Shape.cs +++ b/src/Orchard/DisplayManagement/Shapes/Shape.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Orchard.DisplayManagement.Shapes { - public class Shape { - public virtual ShapeAttributes Attributes { get; set; } +namespace Orchard.DisplayManagement.Shapes { + public class Shape : IShape { + public virtual IShapeAttributes Attributes { get; set; } } } diff --git a/src/Orchard/DisplayManagement/Shapes/ShapeAttributes.cs b/src/Orchard/DisplayManagement/Shapes/ShapeAttributes.cs index a5977a84a..486820e6d 100644 --- a/src/Orchard/DisplayManagement/Shapes/ShapeAttributes.cs +++ b/src/Orchard/DisplayManagement/Shapes/ShapeAttributes.cs @@ -1,5 +1,5 @@ namespace Orchard.DisplayManagement.Shapes { - public class ShapeAttributes { + public class ShapeAttributes : IShapeAttributes { public string Type { get; set; } public string Position { get; set; } } diff --git a/src/Orchard/DisplayManagement/Speculation/DefaultShapeTableFactory.cs b/src/Orchard/DisplayManagement/Speculation/DefaultShapeTableFactory.cs index f92ffb692..0faabbab7 100644 --- a/src/Orchard/DisplayManagement/Speculation/DefaultShapeTableFactory.cs +++ b/src/Orchard/DisplayManagement/Speculation/DefaultShapeTableFactory.cs @@ -1,13 +1,19 @@ -using System.Collections.Generic; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Reflection; +using System.Runtime.CompilerServices; using System.Web; +using Microsoft.CSharp.RuntimeBinder; +using Binder = Microsoft.CSharp.RuntimeBinder.Binder; namespace Orchard.DisplayManagement { public class DefaultShapeTableFactory : IShapeTableFactory { - private readonly IEnumerable _shapeProviders; + private readonly IEnumerable _shapeProviders; - public DefaultShapeTableFactory(IEnumerable shapeProviders) { + public DefaultShapeTableFactory(IEnumerable shapeProviders) { _shapeProviders = shapeProviders; } @@ -29,13 +35,13 @@ namespace Orchard.DisplayManagement { } } - private object PerformInvoke(DisplayContext displayContext, MethodInfo methodInfo, IShapeProvider shapeProvider) { + private object PerformInvoke(DisplayContext displayContext, MethodInfo methodInfo, IShapeDriver shapeDriver) { // oversimplification for the sake of evolving dynamic shape = displayContext.Value; var arguments = methodInfo.GetParameters() .Select(parameter => BindParameter(displayContext, parameter)); - return methodInfo.Invoke(shapeProvider, arguments.ToArray()); + return methodInfo.Invoke(shapeDriver, arguments.ToArray()); } private object BindParameter(DisplayContext displayContext, ParameterInfo parameter) { @@ -45,9 +51,29 @@ namespace Orchard.DisplayManagement { if (parameter.Name == "Display") return displayContext.Display; - return ((dynamic)(displayContext.Value))[parameter.Name]; + var result = ((dynamic)(displayContext.Value))[parameter.Name]; + var converter = _converters.GetOrAdd( + parameter.ParameterType, + CompileConverter); + return converter(result); } + static Func CompileConverter(Type targetType) { + var valueParameter = Expression.Parameter(typeof (object), "value"); + + return Expression.Lambda>( + Expression.Convert( + Expression.Dynamic( + Binder.Convert(CSharpBinderFlags.ConvertExplicit, targetType, null), + targetType, + valueParameter), + typeof (object)), + valueParameter).Compile(); + } + + static readonly ConcurrentDictionary> _converters = + new ConcurrentDictionary>(); + static bool IsAcceptableMethod(MethodInfo methodInfo) { if (methodInfo.IsSpecialName) return false; diff --git a/src/Orchard/DisplayManagement/Speculation/IShapeProvider.cs b/src/Orchard/DisplayManagement/Speculation/IShapeProvider.cs deleted file mode 100644 index 69046e702..000000000 --- a/src/Orchard/DisplayManagement/Speculation/IShapeProvider.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Orchard.DisplayManagement { - public interface IShapeProvider : IDependency{} -} \ No newline at end of file diff --git a/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs b/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs index cbca604bd..c21f476ab 100644 --- a/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs +++ b/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs @@ -35,7 +35,7 @@ namespace Orchard.Mvc.ViewEngines.Razor { contextualize(); _localizer = LocalizationUtilities.Resolve(ViewContext, VirtualPath); - _display = DisplayHelperFactory.CreateDisplayHelper(ViewContext, this); + _display = DisplayHelperFactory.CreateHelper(ViewContext, this); } diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 320c51706..3c0e5db95 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -377,22 +377,24 @@ Code - - - - + + + + + + - - - - - - + + + + + + - - + +