Post-merge fixes and cleanup

--HG--
branch : mvc3p1
This commit is contained in:
Nathan Heskew
2010-08-30 22:07:45 -07:00
parent e4e8bdf84c
commit 470711db50
4 changed files with 49 additions and 117 deletions

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

View File

@@ -5,23 +5,28 @@ using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Autofac;
using Autofac.Core;
using ClaySharp.Implementation;
using Microsoft.CSharp.RuntimeBinder;
using Orchard.DisplayManagement.Implementation;
using Orchard.Environment;
namespace Orchard.DisplayManagement.Descriptors.ShapeAttributeStrategy {
public class ShapeAttributeBindingStrategy : IShapeDescriptorBindingStrategy {
private readonly IEnumerable<ShapeAttributeOccurrence> _shapeAttributeOccurrences;
private readonly IComponentContext _componentContext;
private readonly IComponentContext _componentContext;
private readonly RouteCollection _routeCollection;
public ShapeAttributeBindingStrategy(
IEnumerable<ShapeAttributeOccurrence> shapeAttributeOccurrences,
IComponentContext componentContext) {
IComponentContext componentContext,
RouteCollection routeCollection) {
_shapeAttributeOccurrences = shapeAttributeOccurrences;
// todo: using a component context won't work when this is singleton
_componentContext = componentContext;
_routeCollection = routeCollection;
}
public void Discover(ShapeTableBuilder builder) {
@@ -65,11 +70,29 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeAttributeStrategy {
if (parameter.Name == "Display")
return displayContext.Display;
if (parameter.Name == "Attributes") {
var attributes = new RouteValueDictionary(((dynamic)(displayContext.Value))[parameter.Name]);
return Arguments.From(attributes.Values, attributes.Keys);
}
// meh
if (parameter.Name == "Html") {
return new HtmlHelper(
displayContext.ViewContext,
new ViewDataContainer { ViewData = displayContext.ViewContext.ViewData },
_routeCollection);
}
var result = ((dynamic)(displayContext.Value))[parameter.Name];
var converter = _converters.GetOrAdd(parameter.ParameterType, CompileConverter);
return converter.Invoke((object)result);
}
// ++meh
class ViewDataContainer : IViewDataContainer {
public ViewDataDictionary ViewData { get; set; }
}
static readonly ConcurrentDictionary<Type, Func<object, object>> _converters =
new ConcurrentDictionary<Type, Func<object, object>>();

View File

@@ -1,105 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;
using ClaySharp.Implementation;
using Microsoft.CSharp.RuntimeBinder;
using Orchard.DisplayManagement.Implementation;
using Binder = Microsoft.CSharp.RuntimeBinder.Binder;
namespace Orchard.DisplayManagement {
public class DefaultShapeTableFactory : IShapeTableFactory {
private readonly IEnumerable<IShapeDriver> _shapeProviders;
private readonly RouteCollection _routeCollection;
public DefaultShapeTableFactory(IEnumerable<IShapeDriver> shapeProviders, RouteCollection routeCollection) {
_shapeProviders = shapeProviders;
_routeCollection = routeCollection;
}
public ShapeTable CreateShapeTable() {
var table = new ShapeTable { Entries = GetEntries().ToDictionary(e => e.ShapeType) };
return table;
}
private IEnumerable<ShapeTable.Entry> GetEntries() {
foreach (var shapeProvider in _shapeProviders) {
foreach (var methodInfo in shapeProvider.GetType().GetMethods().Where(IsAcceptableMethod)) {
var info = methodInfo;
var provider = shapeProvider;
yield return new ShapeTable.Entry {
ShapeType = methodInfo.Name,
Target = ctx => PerformInvoke(ctx, info, provider)
};
}
}
}
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(shapeDriver, arguments.ToArray());
}
private object BindParameter(DisplayContext displayContext, ParameterInfo parameter) {
if (parameter.Name == "Shape")
return displayContext.Value;
if (parameter.Name == "Display")
return displayContext.Display;
if (parameter.Name == "Attributes") {
var attributes = new RouteValueDictionary(((dynamic) (displayContext.Value))[parameter.Name]);
return Arguments.From(attributes.Values, attributes.Keys);
}
if (parameter.Name == "Html") {
return new HtmlHelper(
displayContext.ViewContext,
new ViewDataContainer { ViewData = displayContext.ViewContext.ViewData },
_routeCollection);
}
var result = ((dynamic)(displayContext.Value))[parameter.Name];
var converter = _converters.GetOrAdd(
parameter.ParameterType,
CompileConverter);
return converter(result);
}
class ViewDataContainer : IViewDataContainer {
public ViewDataDictionary ViewData { get; set; }
}
static Func<object, object> CompileConverter(Type targetType) {
var valueParameter = Expression.Parameter(typeof (object), "value");
return Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Dynamic(
Binder.Convert(CSharpBinderFlags.ConvertExplicit, targetType, null),
targetType,
valueParameter),
typeof (object)),
valueParameter).Compile();
}
static readonly ConcurrentDictionary<Type, Func<object, object>> _converters =
new ConcurrentDictionary<Type, Func<object, object>>();
static bool IsAcceptableMethod(MethodInfo methodInfo) {
if (methodInfo.IsSpecialName)
return false;
if (methodInfo.DeclaringType == typeof(object))
return false;
return true;
}
}
}

View File

@@ -7,16 +7,16 @@ using System.Web.Mvc.Html;
using System.Web.Routing;
using ClaySharp;
using Orchard.DisplayManagement;
using Orchard.Localization;
namespace Orchard.Mvc.Html {
public class Shapes : IShapeDriver {
public class Shapes : IDependency {
public Shapes(IShapeHelperFactory shapeHelperFactory) {
New = shapeHelperFactory.CreateHelper();
}
dynamic New { get; set; }
[Shape]
public IHtmlString Link(dynamic Display, object Content, string Url, INamedEnumerable<object> Attributes) {
var a = new TagBuilder("a") {
InnerHtml = Display(Content).ToString()
@@ -26,6 +26,7 @@ namespace Orchard.Mvc.Html {
return Display(new HtmlString(a.ToString()));
}
[Shape]
public IHtmlString Image(dynamic Display, string Url, INamedEnumerable<object> Attributes) {
var img = new TagBuilder("img");
img.MergeAttributes(Attributes.Named);
@@ -33,6 +34,7 @@ namespace Orchard.Mvc.Html {
return Display(new HtmlString(img.ToString(TagRenderMode.SelfClosing)));
}
[Shape]
public IHtmlString UnorderedList(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes) {
var ul = new TagBuilder("ul") {
InnerHtml = Combine(DisplayAll(Display, Shape, New.ListItem())).ToString()
@@ -41,6 +43,7 @@ namespace Orchard.Mvc.Html {
return Display(new HtmlString(ul.ToString()));
}
[Shape]
public IHtmlString ListItem(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes) {
var li = new TagBuilder("li") {
InnerHtml = Display(Shape.Content).ToString()
@@ -53,6 +56,7 @@ namespace Orchard.Mvc.Html {
#region form and company
[Shape]
public IHtmlString Form(dynamic Display, dynamic Shape, object Submit, INamedEnumerable<object> Attributes, HtmlHelper Html) {
var form = new TagBuilder("form") {
InnerHtml = Display(Shape.Fieldsets).ToString()
@@ -66,10 +70,12 @@ namespace Orchard.Mvc.Html {
return Display(new HtmlString(form.ToString()));
}
[Shape]
public IHtmlString Fieldsets(dynamic Display, dynamic Shape) {
return Display(new HtmlString(Combine(DisplayAll(Display, Shape)).ToString()));
}
[Shape]
public IHtmlString Fieldset(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes) {
var fieldset = new TagBuilder("fieldset");
fieldset.MergeAttributes(Attributes.Named);
@@ -77,7 +83,7 @@ namespace Orchard.Mvc.Html {
fieldset.MergeAttribute("class", Shape.Name);
if (Shape.Count > 1) {
Shape.ShapeMetadata.Type = "UnorderedList";
Shape.Metadata.Type = "UnorderedList";
fieldset.InnerHtml = Display(Shape).ToString();
}
else {
@@ -87,6 +93,7 @@ namespace Orchard.Mvc.Html {
return Display(new HtmlString(fieldset.ToString()));
}
[Shape]
public IHtmlString FormButton(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes) {
var button = new TagBuilder("button") {
InnerHtml = Display(Shape.Text).ToString() //not caring about anything other than text at the moment
@@ -95,12 +102,14 @@ namespace Orchard.Mvc.Html {
return Display(new HtmlString(button.ToString()));
}
[Shape]
public IHtmlString FormSubmit(dynamic Display, dynamic Shape) {
Shape.ShapeMetadata.Type = "FormButton";
Shape.Metadata.Type = "FormButton";
Shape.Attributes(new { type = "submit" });
return Display(Shape);
}
[Shape]
public IHtmlString Input(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes, HtmlHelper Html) {
var input = new TagBuilder("input");
input.MergeAttributes(Attributes.Named);
@@ -111,10 +120,13 @@ namespace Orchard.Mvc.Html {
new HtmlString(input.ToString(TagRenderMode.SelfClosing)),
New.ValidationMessage().For(Shape));
}
[Shape]
public IHtmlString ValidationMessage(dynamic Display, dynamic For, HtmlHelper Html) {
return Display(Html.ValidationMessage(For.Name as string));
}
[Shape]
public IHtmlString Label(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes) {
var label = new TagBuilder("label") {
InnerHtml = Display(Shape.Text).ToString()
@@ -123,12 +135,14 @@ namespace Orchard.Mvc.Html {
return Display(new HtmlString(label.ToString()));
}
[Shape]
public IHtmlString Text(dynamic Shape) {
return new HtmlString(Shape.ToString());
}
[Shape]
public IHtmlString InputPassword(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes) {
Shape.ShapeMetadata.Type = "Input";
Shape.Metadata.Type = "Input";
var attributes = new RouteValueDictionary(Attributes.Named);
attributes["type"] = "password";
Shape.Attributes(attributes);
@@ -137,9 +151,10 @@ namespace Orchard.Mvc.Html {
Shape);
}
[Shape]
public IHtmlString InputText(dynamic Display, dynamic Shape, INamedEnumerable<object> Attributes) {
Shape.ShapeMetadata.Type = "Input";
//could use a mergeattributes equiv if we go down this route
Shape.Metadata.Type = "Input";
// could use a mergeattributes equiv if we go down this route
// also, Attributes.Named["type"] and equiv are NYI (INamedEnumerable is awesome but currently R/O)
var attributes = new RouteValueDictionary(Attributes.Named);
attributes["type"] = "text";