// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace System.Web.Mvc { // This class assumes that model metadata is expensive to create, and allows the user to // stash a cache object that can be copied around as a prototype to make creation and // computation quicker. It delegates the retrieval of values to getter methods, the results // of which are cached on a per-metadata-instance basis. // // This allows flexible caching strategies: either caching the source of information across // instances or caching of the actual information itself, depending on what the developer // decides to put into the prototype cache. public abstract class CachedModelMetadata : ModelMetadata { private bool _convertEmptyStringToNull; private string _dataTypeName; private string _description; private string _displayFormatString; private string _displayName; private string _editFormatString; private bool _hasNonDefaultEditFormat; private bool _hideSurroundingHtml; private bool _htmlEncode; private bool _isReadOnly; private bool _isRequired; private string _nullDisplayText; private int _order; private string _shortDisplayName; private bool _showForDisplay; private bool _showForEdit; private string _templateHint; private string _watermark; private bool _convertEmptyStringToNullComputed; private bool _dataTypeNameComputed; private bool _descriptionComputed; private bool _displayFormatStringComputed; private bool _displayNameComputed; private bool _editFormatStringComputed; private bool _hasNonDefaultEditFormatComputed; private bool _hideSurroundingHtmlComputed; private bool _htmlEncodeComputed; private bool _isReadOnlyComputed; private bool _isRequiredComputed; private bool _nullDisplayTextComputed; private bool _orderComputed; private bool _shortDisplayNameComputed; private bool _showForDisplayComputed; private bool _showForEditComputed; private bool _templateHintComputed; private bool _watermarkComputed; // Constructor for creating real instances of the metadata class based on a prototype protected CachedModelMetadata(CachedModelMetadata prototype, Func modelAccessor) : base(prototype.Provider, prototype.ContainerType, modelAccessor, prototype.ModelType, prototype.PropertyName) { PrototypeCache = prototype.PrototypeCache; } // Constructor for creating the prototype instances of the metadata class protected CachedModelMetadata(CachedDataAnnotationsModelMetadataProvider provider, Type containerType, Type modelType, string propertyName, TPrototypeCache prototypeCache) : base(provider, containerType, null /* modelAccessor */, modelType, propertyName) { PrototypeCache = prototypeCache; } public sealed override bool ConvertEmptyStringToNull { get { if (!_convertEmptyStringToNullComputed) { _convertEmptyStringToNull = ComputeConvertEmptyStringToNull(); _convertEmptyStringToNullComputed = true; } return _convertEmptyStringToNull; } set { _convertEmptyStringToNull = value; _convertEmptyStringToNullComputed = true; } } public sealed override string DataTypeName { get { if (!_dataTypeNameComputed) { _dataTypeName = ComputeDataTypeName(); _dataTypeNameComputed = true; } return _dataTypeName; } set { _dataTypeName = value; _dataTypeNameComputed = true; } } public sealed override string Description { get { if (!_descriptionComputed) { _description = ComputeDescription(); _descriptionComputed = true; } return _description; } set { _description = value; _descriptionComputed = true; } } public sealed override string DisplayFormatString { get { if (!_displayFormatStringComputed) { _displayFormatString = ComputeDisplayFormatString(); _displayFormatStringComputed = true; } return _displayFormatString; } set { _displayFormatString = value; _displayFormatStringComputed = true; } } public sealed override string DisplayName { get { if (!_displayNameComputed) { _displayName = ComputeDisplayName(); _displayNameComputed = true; } return _displayName; } set { _displayName = value; _displayNameComputed = true; } } public sealed override string EditFormatString { get { if (!_editFormatStringComputed) { _editFormatString = ComputeEditFormatString(); _editFormatStringComputed = true; } return _editFormatString; } set { _editFormatString = value; _editFormatStringComputed = true; } } internal sealed override bool HasNonDefaultEditFormat { get { if (!_hasNonDefaultEditFormatComputed) { _hasNonDefaultEditFormat = ComputeHasNonDefaultEditFormat(); _hasNonDefaultEditFormatComputed = true; } return _hasNonDefaultEditFormat; } set { _hasNonDefaultEditFormat = value; _hasNonDefaultEditFormatComputed = true; } } public sealed override bool HideSurroundingHtml { get { if (!_hideSurroundingHtmlComputed) { _hideSurroundingHtml = ComputeHideSurroundingHtml(); _hideSurroundingHtmlComputed = true; } return _hideSurroundingHtml; } set { _hideSurroundingHtml = value; _hideSurroundingHtmlComputed = true; } } public sealed override bool HtmlEncode { get { if (!_htmlEncodeComputed) { _htmlEncode = ComputeHtmlEncode(); _htmlEncodeComputed = true; } return _htmlEncode; } set { _htmlEncode = value; _htmlEncodeComputed = true; } } public sealed override bool IsReadOnly { get { if (!_isReadOnlyComputed) { _isReadOnly = ComputeIsReadOnly(); _isReadOnlyComputed = true; } return _isReadOnly; } set { _isReadOnly = value; _isReadOnlyComputed = true; } } public sealed override bool IsRequired { get { if (!_isRequiredComputed) { _isRequired = ComputeIsRequired(); _isRequiredComputed = true; } return _isRequired; } set { _isRequired = value; _isRequiredComputed = true; } } public sealed override string NullDisplayText { get { if (!_nullDisplayTextComputed) { _nullDisplayText = ComputeNullDisplayText(); _nullDisplayTextComputed = true; } return _nullDisplayText; } set { _nullDisplayText = value; _nullDisplayTextComputed = true; } } public sealed override int Order { get { if (!_orderComputed) { _order = ComputeOrder(); _orderComputed = true; } return _order; } set { _order = value; _orderComputed = true; } } protected TPrototypeCache PrototypeCache { get; set; } public sealed override string ShortDisplayName { get { if (!_shortDisplayNameComputed) { _shortDisplayName = ComputeShortDisplayName(); _shortDisplayNameComputed = true; } return _shortDisplayName; } set { _shortDisplayName = value; _shortDisplayNameComputed = true; } } public sealed override bool ShowForDisplay { get { if (!_showForDisplayComputed) { _showForDisplay = ComputeShowForDisplay(); _showForDisplayComputed = true; } return _showForDisplay; } set { _showForDisplay = value; _showForDisplayComputed = true; } } public sealed override bool ShowForEdit { get { if (!_showForEditComputed) { _showForEdit = ComputeShowForEdit(); _showForEditComputed = true; } return _showForEdit; } set { _showForEdit = value; _showForEditComputed = true; } } public sealed override string SimpleDisplayText { get { // This is already cached in the base class with an appropriate override available return base.SimpleDisplayText; } set { base.SimpleDisplayText = value; } } public sealed override string TemplateHint { get { if (!_templateHintComputed) { _templateHint = ComputeTemplateHint(); _templateHintComputed = true; } return _templateHint; } set { _templateHint = value; _templateHintComputed = true; } } public sealed override string Watermark { get { if (!_watermarkComputed) { _watermark = ComputeWatermark(); _watermarkComputed = true; } return _watermark; } set { _watermark = value; _watermarkComputed = true; } } protected virtual bool ComputeConvertEmptyStringToNull() { return base.ConvertEmptyStringToNull; } protected virtual string ComputeDataTypeName() { return base.DataTypeName; } protected virtual string ComputeDescription() { return base.Description; } protected virtual string ComputeDisplayFormatString() { return base.DisplayFormatString; } protected virtual string ComputeDisplayName() { return base.DisplayName; } protected virtual string ComputeEditFormatString() { return base.EditFormatString; } protected virtual bool ComputeHasNonDefaultEditFormat() { return base.HasNonDefaultEditFormat; } protected virtual bool ComputeHideSurroundingHtml() { return base.HideSurroundingHtml; } protected virtual bool ComputeHtmlEncode() { return base.HtmlEncode; } protected virtual bool ComputeIsReadOnly() { return base.IsReadOnly; } protected virtual bool ComputeIsRequired() { return base.IsRequired; } protected virtual string ComputeNullDisplayText() { return base.NullDisplayText; } protected virtual int ComputeOrder() { return base.Order; } protected virtual string ComputeShortDisplayName() { return base.ShortDisplayName; } protected virtual bool ComputeShowForDisplay() { return base.ShowForDisplay; } protected virtual bool ComputeShowForEdit() { return base.ShowForEdit; } protected virtual string ComputeSimpleDisplayText() { return base.GetSimpleDisplayText(); } protected virtual string ComputeTemplateHint() { return base.TemplateHint; } protected virtual string ComputeWatermark() { return base.Watermark; } protected sealed override string GetSimpleDisplayText() { // Rename for consistency return ComputeSimpleDisplayText(); } } }