diff --git a/src/MvcExtensions.FluentMetadata/ModelMetadata/HtmlSelectModelMetadataItemBuilderExtensions.cs b/src/MvcExtensions.FluentMetadata/ModelMetadata/HtmlSelectModelMetadataItemBuilderExtensions.cs index 9396e77..af245d7 100644 --- a/src/MvcExtensions.FluentMetadata/ModelMetadata/HtmlSelectModelMetadataItemBuilderExtensions.cs +++ b/src/MvcExtensions.FluentMetadata/ModelMetadata/HtmlSelectModelMetadataItemBuilderExtensions.cs @@ -1,133 +1,133 @@ -#region Copyright -// Copyright (c) 2009 - 2011, Kazi Manzur Rashid . -// This source is subject to the Microsoft Public License. -// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. -// All other rights reserved. -#endregion - -namespace MvcExtensions -{ - using System; +#region Copyright +// Copyright (c) 2009 - 2011, Kazi Manzur Rashid . +// This source is subject to the Microsoft Public License. +// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. +// All other rights reserved. +#endregion + +namespace MvcExtensions +{ + using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using JetBrains.Annotations; - /// - /// Extensions for which add AsDropDownList and AsListBox methods + /// + /// Extensions for which add AsDropDownList and AsListBox methods /// [TypeForwardedFrom(KnownAssembly.MvcExtensions)] - public static class HtmlSelectModelMetadataItemBuilderExtensions - { - /// - /// Marks the value to render as DropDownList element in edit mode. - /// - /// The instance. - /// The view data key, the value of the view data key must be a . + public static class HtmlSelectModelMetadataItemBuilderExtensions + { + /// + /// Marks the value to render as DropDownList element in edit mode. + /// + /// The instance. + /// The view data key, the value of the view data key must be a . /// [NotNull] - public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey) - { - return self.AsDropDownList(viewDataKey, (Func)null); - } - - /// - /// Marks the value to render as DropDownList element in edit mode. - /// - /// The instance. - /// The view data key, the value of the view data key must be a . - /// The option label. + public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey) + { + return self.AsDropDownList(viewDataKey, (Func)null); + } + + /// + /// Marks the value to render as DropDownList element in edit mode. + /// + /// The instance. + /// The view data key, the value of the view data key must be a . + /// The option label. /// [NotNull] - public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, string optionLabel) - { - return self.AsDropDownList(viewDataKey, () => optionLabel); - } - - /// - /// Marks the value to render as DropDownList element in edit mode. - /// - /// The instance. - /// The view data key, the value of the view data key must be a . - /// The option label. + public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, string optionLabel) + { + return self.AsDropDownList(viewDataKey, () => optionLabel); + } + + /// + /// Marks the value to render as DropDownList element in edit mode. + /// + /// The instance. + /// The view data key, the value of the view data key must be a . + /// The option label. /// [NotNull] - public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, Func optionLabel) - { - return self.AsDropDownList(viewDataKey, optionLabel, "DropDownList"); - } - - /// - /// Marks the value to render as DropDownList element in edit mode. - /// - /// The instance. - /// The view data key. - /// The option label. - /// The template. + public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, Func optionLabel) + { + return self.AsDropDownList(viewDataKey, optionLabel, "DropDownList"); + } + + /// + /// Marks the value to render as DropDownList element in edit mode. + /// + /// The instance. + /// The view data key. + /// The option label. + /// The template. /// [NotNull] - public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, string optionLabel, [AspMvcEditorTemplate, AspMvcDisplayTemplate]string template) - { - return self.AsDropDownList(viewDataKey, () => optionLabel, template); - } - - /// - /// Marks the value to render as DropDownList element in edit mode. - /// - /// The instance. - /// The view data key. - /// The option label. - /// The template. + public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, string optionLabel, [AspMvcEditorTemplate, AspMvcDisplayTemplate]string template) + { + return self.AsDropDownList(viewDataKey, () => optionLabel, template); + } + + /// + /// Marks the value to render as DropDownList element in edit mode. + /// + /// The instance. + /// The view data key. + /// The option label. + /// The template. /// [NotNull] - public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, Func optionLabel, [AspMvcEditorTemplate, AspMvcDisplayTemplate]string template) - { - return HtmlSelect(self, template, viewDataKey, optionLabel); - } - - /// - /// Marks the value to render as ListBox in edit mode. - /// - /// The instance. - /// The view data key, the value of the view data key must be a . + public static ModelMetadataItemBuilder AsDropDownList([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, Func optionLabel, [AspMvcEditorTemplate, AspMvcDisplayTemplate]string template) + { + return HtmlSelect(self, template, viewDataKey, optionLabel); + } + + /// + /// Marks the value to render as ListBox in edit mode. + /// + /// The instance. + /// The view data key, the value of the view data key must be a . /// [NotNull] - public static ModelMetadataItemBuilder AsListBox([NotNull] this ModelMetadataItemBuilder self, string viewDataKey) - { - return self.AsListBox(viewDataKey, "ListBox"); - } - - /// - /// Marks the value to render as ListBox in edit mode. - /// - /// The instance. - /// The view data key. - /// The template. + public static ModelMetadataItemBuilder AsListBox([NotNull] this ModelMetadataItemBuilder self, string viewDataKey) + { + return self.AsListBox(viewDataKey, "ListBox"); + } + + /// + /// Marks the value to render as ListBox in edit mode. + /// + /// The instance. + /// The view data key. + /// The template. /// [NotNull] - public static ModelMetadataItemBuilder AsListBox([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, [AspMvcEditorTemplate, AspMvcDisplayTemplate]string template) - { - return HtmlSelect(self, template, viewDataKey, null); + public static ModelMetadataItemBuilder AsListBox([NotNull] this ModelMetadataItemBuilder self, string viewDataKey, [AspMvcEditorTemplate, AspMvcDisplayTemplate]string template) + { + return HtmlSelect(self, template, viewDataKey, null); } [NotNull] - private static ModelMetadataItemBuilder HtmlSelect([NotNull] ModelMetadataItemBuilder self, string templateName, string viewDataKey, Func optionLabel) - { - self.AddAction( - m => - { - var selectableElementSetting = m.GetAdditionalSettingOrCreateNew(); - - selectableElementSetting.ViewDataKey = viewDataKey; - - if (optionLabel != null) - { - selectableElementSetting.OptionLabel = optionLabel; - } - - m.TemplateName = templateName; - }); - - return self; - } - } + private static ModelMetadataItemBuilder HtmlSelect([NotNull] ModelMetadataItemBuilder self, string templateName, string viewDataKey, Func optionLabel) + { + self.AddAction( + m => + { + var selectableElementSetting = m.GetAdditionalSettingOrCreateNew(); + + selectableElementSetting.ViewDataKey = viewDataKey; + + if (optionLabel != null) + { + selectableElementSetting.OptionLabel = optionLabel; + } + + m.TemplateName = templateName; + }); + + return self; + } + } } \ No newline at end of file diff --git a/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataConfiguration.cs b/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataConfiguration.cs index f6252ec..3df5332 100644 --- a/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataConfiguration.cs +++ b/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataConfiguration.cs @@ -11,15 +11,15 @@ namespace MvcExtensions using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; - using System.Linq.Expressions; - using System.Runtime.CompilerServices; - using System.Web.Mvc; - using JetBrains.Annotations; - + using System.Linq.Expressions; + using System.Runtime.CompilerServices; + using System.Web.Mvc; + using JetBrains.Annotations; + /// /// Defines a base class that is used to configure metadata of a model fluently. - /// - [TypeForwardedFrom(KnownAssembly.MvcExtensions)] + /// + [TypeForwardedFrom(KnownAssembly.MvcExtensions)] public abstract class ModelMetadataConfiguration : IModelMetadataConfiguration where TModel : class { private readonly IDictionary configurations = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -52,8 +52,8 @@ public virtual IDictionary Configuration /// /// The type of the value. /// The expression. - /// - [NotNull] + /// + [NotNull] protected ModelMetadataItemBuilder Configure([NotNull] Expression> expression) { Invariant.IsNotNull(expression, "expression"); @@ -61,9 +61,7 @@ protected ModelMetadataItemBuilder Configure([NotNull] Expressio string property = ExpressionHelper.GetExpressionText(expression); Invariant.IsNotNull(property, "property"); - var builder = new ModelMetadataItemBuilder(new ModelMetadataItem()); - configurations[property] = builder; - return builder; + return GetOrCreate(property); } /// @@ -71,38 +69,38 @@ protected ModelMetadataItemBuilder Configure([NotNull] Expressio /// /// The type of the value. /// The expression. - /// - [NotNull] + /// + [NotNull] protected ModelMetadataItemBuilder Configure([NotNull] string property) { - Invariant.IsNotNull(property, "property"); - - return Create(property); + Invariant.IsNotNull(property, "property"); + + return GetOrCreate(property); } /// /// Configures the specified value. /// /// The expression. - /// - [NotNull] + /// + [NotNull] protected ModelMetadataItemBuilder Configure([NotNull] string property) { Invariant.IsNotNull(property, "property"); - var item = new ModelMetadataItem(); - - var builder = new ModelMetadataItemBuilder(item); - configurations[property] = builder; - return builder; + return GetOrCreate(property); } - private ModelMetadataItemBuilder Create(string property) + private ModelMetadataItemBuilder GetOrCreate(string property) { - var builder = new ModelMetadataItemBuilder(new ModelMetadataItem()); - - configurations[property] = builder; + if (!configurations.ContainsKey(property)) + { + var builder = new ModelMetadataItemBuilder(new ModelMetadataItem()); + + configurations[property] = builder; + return builder; + } - return builder; + return (ModelMetadataItemBuilder)configurations[property]; } } } \ No newline at end of file diff --git a/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItem.cs b/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItem.cs index 0deca2f..da9883d 100644 --- a/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItem.cs +++ b/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItem.cs @@ -3,8 +3,10 @@ // This source is subject to the Microsoft Public License. // See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. // All other rights reserved. -#endregion - +#endregion + +using System.Web.Mvc; + namespace MvcExtensions { using System; @@ -25,6 +27,7 @@ public ModelMetadataItem() ShowForDisplay = true; Validations = new List(); AdditionalSettings = new List(); + MetadataAwares = new List(); } /// @@ -165,7 +168,12 @@ public IList AdditionalSettings { get; private set; - } + } + + /// + /// Gets the MetadataAwares + /// + public IList MetadataAwares { get; private set; } /// /// Gets or sets the order. diff --git a/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItemExtensions.cs b/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItemExtensions.cs index c10960b..0fa5ce5 100644 --- a/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItemExtensions.cs +++ b/src/MvcExtensions.FluentMetadata/ModelMetadata/ModelMetadataItemExtensions.cs @@ -3,8 +3,10 @@ // This source is subject to the Microsoft Public License. // See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. // All other rights reserved. -#endregion - +#endregion + +using System.Web.Mvc; + namespace MvcExtensions { using System.Linq; @@ -85,6 +87,42 @@ public static TSetting GetAdditionalSetting([NotNull] this ModelMetada where TSetting : IModelMetadataAdditionalSetting { return item.AdditionalSettings.OfType().FirstOrDefault(); + } + + + /// + /// Returns model metadataAware of type associated with this . + /// New model setting will be created if no one is found. + /// + /// + /// + /// Model validation metadata of type + [NotNull] + public static TSetting GetMetadataAwareOrCreateNew([NotNull] this ModelMetadataItem item) + where TSetting : class, IMetadataAware, new() + { + var setting = item.GetMetadataAware(); + + if (setting == null) + { + setting = new TSetting(); + item.MetadataAwares.Add(setting); + } + + return setting; + } + + /// + /// Returns model metadataAware of type associated with this or null. + /// + /// + /// + /// Model validation metadata of type or null + [CanBeNull] + public static TSetting GetMetadataAware([NotNull] this ModelMetadataItem item) + where TSetting : IMetadataAware + { + return item.MetadataAwares.OfType().FirstOrDefault(); } } } \ No newline at end of file diff --git a/src/MvcExtensions.FluentMetadata/Providers/ExtendedModelMetadataProvider.cs b/src/MvcExtensions.FluentMetadata/Providers/ExtendedModelMetadataProvider.cs index 1898543..a61cde4 100644 --- a/src/MvcExtensions.FluentMetadata/Providers/ExtendedModelMetadataProvider.cs +++ b/src/MvcExtensions.FluentMetadata/Providers/ExtendedModelMetadataProvider.cs @@ -197,12 +197,32 @@ private static void Copy(ModelMetadataItem metadataItem, ModelMetadata metadata) metadata.ConvertEmptyStringToNull = metadataItem.ConvertEmptyStringToNull.Value; } + foreach (var item in metadataItem.MetadataAwares) + { + item.OnMetadataCreated(metadata); + } + FluentModelMetadataTransformer.Transform(metadata); MvcExtensions.DisplayNameTransformer.Transform(metadata); } [NotNull] - private ModelMetadata CreatePropertyMetadata(Type containerType, string propertyName, Type propertyType, ModelMetadataItem propertyMetadata, Func modelAccessor) + private ModelMetadata CreateModelMetadata(Type modelType, Func modelAccessor, ModelMetadataItem metadataItem) + { + ModelMetadata modelMetadata = new ExtendedModelMetadata(this, null, modelAccessor, modelType, null, metadataItem); + + if (metadataItem != null) + { + Copy(metadataItem, modelMetadata); + + } + + return modelMetadata; + } + + [NotNull] + private ModelMetadata CreatePropertyMetadata( + Type containerType, string propertyName, Type propertyType, ModelMetadataItem propertyMetadata, Func modelAccessor) { ModelMetadata modelMetadata = new ExtendedModelMetadata(this, containerType, modelAccessor, propertyType, propertyName, propertyMetadata);