我最喜爱的框架/库使用扩展方法严重。 autofac期间使用登记和ASP.NET MVC3的HTML Helper的扩展方法。由于扩展方法是静态的,它们是封闭的扩展。这是面向对象编程的最重要原则之一。
为MVC,我想能够自动添加一个提示,所有的编辑器和标签。其实很简单,我只是想添加"称号??归因于所有生成的ModelMetadata包含一个HTML元素"描述??为LabelFor的源代码看起来像这样: public static class LabelExtensions {
public static MvcHtmlString Label(this HtmlHelper html, string expression) {
return LabelHelper(html,
ModelMetadata.FromStringExpression(expression, html.ViewData),
expression);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
return LabelHelper(html,
ModelMetadata.FromLambdaExpression(expression, html.ViewData),
ExpressionHelper.GetExpressionText(expression));
}
public static MvcHtmlString LabelForModel(this HtmlHelper html) {
return LabelHelper(html, html.ViewData.ModelMetadata, String.Empty);
}
internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName) {
string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
if (String.IsNullOrEmpty(labelText)) {
return MvcHtmlString.Empty;
}
TagBuilder tag = new TagBuilder("label");
tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
tag.SetInnerText(labelText);
return tag.ToMvcHtmlString(TagRenderMode.Normal);
}
}
,因此,它是不可能做任何有关帮手。我不明白他们为什么使用扩展方法。这是伟大的,因为它是很容易找到所有可用的佣工。问题是,你不能这样做没有任何修改它们所产生的数据。该解决方案
所有的扩展方法转换为真正实施的外墙,并使用扩展方法DependencyResolver的找到合适的类。创建一些接口和默认实现为所有发电机。
新LabelHelper:{C}
默认实现简单的例子: public class LabelGenerator : ILabelGenerator
{
public virtual void Create(HtmlHelper html, ModelMetadata metadata, string htmlFieldName)
{
string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
if (String.IsNullOrEmpty(labelText)) {
return MvcHtmlString.Empty;
}
TagBuilder tag = new TagBuilder("label");
tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
tag.SetInnerText(labelText);
ProcessTag(tag);
return tag.ToMvcHtmlString(TagRenderMode.Normal);
}
protected virtual void ProcessTag(TagBuilder tag, ModelMetaData metaData)
{
}
}
这将使我创建以下实施:{体C3}
唯一剩下的是注入我的容器中,并创建一个小的jQuery脚本创建实际的工具提示使用"称号??属性。