I would expect a fluent method chain to not produce side effects when a method is invoked more than once. particularly, concerning the ability to apply HtmlAttributes more than once to a method chain. This prevents me from implementing meaningful extension methods to promote a DRY approach to views.
In particular, I am trying to do something like this:
public static TextBoxBuilder<TProperty> PasswordFor<TModel, TProperty>(this WidgetFactory<TModel> widgetFactory, Expression<Func<TModel, TProperty>> expression)
{
return widgetFactory.TextBoxFor(expression).HtmlAttributes(new { type = "password" });
}
public static TextBoxBuilder<TModel> AutoFocus<TModel>(this TextBoxBuilder<TModel> builder)
{
return builder.HtmlAttributes(new { autofocus = true });
}
I am finding that because the HTML attributes is cleared in your base implementation..
this.Component.HtmlAttributes.Clear();
it doesn't support an aggregation of attributes, but instead it's last-man-in. that defeats the purpose of extensibility and effectively insists upon repetition and sort of brittle design that a copy/paste architecture results in.
I would believe it be completely acceptable to give the last-attribute-applied precedence and overwrite the value, but the reality is that we're talking about basic key/value pairs, and it shouldn't be difficult to merge the attributes as they are built. best case, right now i have to implement my own derivation of the WidgetBuilderBase and implement an extension method off the WidgetFactory that bootstraps my functionality - certainly not a stretch, but more work than should probably be necessary.
public virtual TBuilder HtmlAttributes(object attributes)
{
return this.HtmlAttributes(ObjectExtensions.ToDictionary(attributes));
}
public virtual TBuilder HtmlAttributes(IDictionary<string, object> attributes)
{
this.Component.HtmlAttributes.Clear();
Kendo.Mvc.Extensions.DictionaryExtensions.Merge(this.Component.HtmlAttributes, attributes);
return this as TBuilder;
}