static PropertyCacheLevel GetCacheLevel(IPropertyValueConverter converter, PropertyCacheValue value) { if (converter == null) { return(PropertyCacheLevel.Request); } var attr = converter.GetType().GetCustomAttributes <PropertyValueCacheAttribute>(false) .FirstOrDefault(x => x.Value == value || x.Value == PropertyCacheValue.All); return(attr == null ? PropertyCacheLevel.Request : attr.Level); }
private void InitializeLocked() { _converter = null; var isdefault = false; foreach (var converter in _propertyValueConverters) { if (!converter.IsConverter(this)) { continue; } if (_converter == null) { _converter = converter; isdefault = _propertyValueConverters.IsDefault(converter); continue; } if (isdefault) { if (_propertyValueConverters.IsDefault(converter)) { // previous was default, and got another default if (_propertyValueConverters.Shadows(_converter, converter)) { // previous shadows, ignore } else if (_propertyValueConverters.Shadows(converter, _converter)) { // shadows previous, replace _converter = converter; } else { // no shadow - bad throw new InvalidOperationException(string.Format("Type '{2}' cannot be an IPropertyValueConverter" + " for property '{1}' of content type '{0}' because type '{3}' has already been detected as a converter" + " for that property, and only one converter can exist for a property.", ContentType.Alias, Alias, converter.GetType().FullName, _converter.GetType().FullName)); } } else { // previous was default, replaced by non-default _converter = converter; isdefault = false; } } else { if (_propertyValueConverters.IsDefault(converter)) { // previous was non-default, ignore default } else { // previous was non-default, and got another non-default - bad throw new InvalidOperationException(string.Format("Type '{2}' cannot be an IPropertyValueConverter" + " for property '{1}' of content type '{0}' because type '{3}' has already been detected as a converter" + " for that property, and only one converter can exist for a property.", ContentType.Alias, Alias, converter.GetType().FullName, _converter.GetType().FullName)); } } } _cacheLevel = _converter?.GetPropertyCacheLevel(this) ?? PropertyCacheLevel.Snapshot; _modelClrType = _converter == null ? typeof(object) : _converter.GetPropertyValueType(this); }
private void InitializeConverters() { //TODO: Look at optimizing this method, it gets run for every property type for the document being rendered at startup, // every precious second counts! var converters = PropertyValueConvertersResolver.Current.Converters.ToArray(); var defaultConvertersWithAttributes = PropertyValueConvertersResolver.Current.DefaultConverters; _converter = null; //get all converters for this property type // todo: remove Union() once we drop IPropertyEditorValueConverter support. var foundConverters = converters.Union(GetCompatConverters()).Where(x => x.IsConverter(this)).ToArray(); if (foundConverters.Length == 1) { _converter = foundConverters[0]; } else if (foundConverters.Length > 1) { //more than one was found, we need to first figure out if one of these is an Umbraco default value type converter //get the non-default and see if we have one var nonDefault = foundConverters.Except(defaultConvertersWithAttributes.Select(x => x.Item1)).ToArray(); if (nonDefault.Length == 1) { //there's only 1 custom converter registered that so use it _converter = nonDefault[0]; } else if (nonDefault.Length > 1) { //this is not allowed, there cannot be more than 1 custom converter throw new InvalidOperationException( string.Format("Type '{2}' cannot be an IPropertyValueConverter" + " for property '{1}' of content type '{0}' because type '{3}' has already been detected as a converter" + " for that property, and only one converter can exist for a property.", ContentType.Alias, PropertyTypeAlias, nonDefault[1].GetType().FullName, nonDefault[0].GetType().FullName)); } else { //we need to remove any converters that have been shadowed by another converter var foundDefaultConvertersWithAttributes = defaultConvertersWithAttributes.Where(x => foundConverters.Contains(x.Item1)); var shadowedTypes = foundDefaultConvertersWithAttributes.SelectMany(x => x.Item2.DefaultConvertersToShadow); var shadowedDefaultConverters = foundConverters.Where(x => shadowedTypes.Contains(x.GetType())); var nonShadowedDefaultConverters = foundConverters.Except(shadowedDefaultConverters).ToArray(); if (nonShadowedDefaultConverters.Length == 1) { //assign to the single default converter _converter = nonShadowedDefaultConverters[0]; } else if (nonShadowedDefaultConverters.Length > 1) { //this is not allowed, there cannot be more than 1 custom converter throw new InvalidOperationException( string.Format("Type '{2}' cannot be an IPropertyValueConverter" + " for property '{1}' of content type '{0}' because type '{3}' has already been detected as a converter" + " for that property, and only one converter can exist for a property.", ContentType.Alias, PropertyTypeAlias, nonShadowedDefaultConverters[1].GetType().FullName, nonShadowedDefaultConverters[0].GetType().FullName)); } } } var converterMeta = _converter as IPropertyValueConverterMeta; // get the cache levels, quietely fixing the inconsistencies (no need to throw, really) if (converterMeta != null) { _sourceCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Source); _objectCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.Object); _xpathCacheLevel = converterMeta.GetPropertyCacheLevel(this, PropertyCacheValue.XPath); } else { _sourceCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Source); _objectCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.Object); _xpathCacheLevel = GetCacheLevel(_converter, PropertyCacheValue.XPath); } if (_objectCacheLevel < _sourceCacheLevel) { _objectCacheLevel = _sourceCacheLevel; } if (_xpathCacheLevel < _sourceCacheLevel) { _xpathCacheLevel = _sourceCacheLevel; } // get the CLR type of the converted value if (_converter != null) { if (converterMeta != null) { _clrType = converterMeta.GetPropertyValueType(this); } else { var attr = _converter.GetType().GetCustomAttribute <PropertyValueTypeAttribute>(false); if (attr != null) { _clrType = attr.Type; } } } }
static PropertyCacheLevel GetCacheLevel(IPropertyValueConverter converter, PropertyCacheValue value) { if (converter == null) return PropertyCacheLevel.Request; var attr = converter.GetType().GetCustomAttributes<PropertyValueCacheAttribute>(false) .FirstOrDefault(x => x.Value == value || x.Value == PropertyCacheValue.All); return attr == null ? PropertyCacheLevel.Request : attr.Level; }