< Summary

Information
Class: Fluorite.Strainer.Services.Metadata.Attributes.AttributeMetadataRetriever
Assembly: Fluorite.Strainer
File(s): /builds/fluorite/strainer/src/Strainer/Services/Metadata/Attributes/AttributeMetadataRetriever.cs
Line coverage
66%
Covered lines: 97
Uncovered lines: 48
Coverable lines: 145
Total lines: 278
Line coverage: 66.8%
Branch coverage
40%
Covered branches: 24
Total branches: 60
Branch coverage: 40%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/builds/fluorite/strainer/src/Strainer/Services/Metadata/Attributes/AttributeMetadataRetriever.cs

#LineLine coverage
 1using Fluorite.Extensions;
 2using Fluorite.Strainer.Models.Metadata;
 3
 4namespace Fluorite.Strainer.Services.Metadata.Attributes;
 5
 6public class AttributeMetadataRetriever : IAttributeMetadataRetriever
 7{
 8    private readonly IMetadataSourceChecker _metadataSourceChecker;
 9    private readonly IAttributePropertyMetadataBuilder _attributePropertyMetadataBuilder;
 10    private readonly IPropertyMetadataDictionaryProvider _propertyMetadataDictionaryProvider;
 11    private readonly IStrainerAttributeProvider _strainerAttributeProvider;
 12    private readonly IPropertyInfoProvider _propertyInfoProvider;
 13    private readonly IAttributeCriteriaChecker _attributeCriteriaChecker;
 14
 2015    public AttributeMetadataRetriever(
 2016        IMetadataSourceChecker metadataSourceChecker,
 2017        IAttributePropertyMetadataBuilder attributePropertyMetadataBuilder,
 2018        IPropertyMetadataDictionaryProvider propertyMetadataDictionaryProvider,
 2019        IStrainerAttributeProvider strainerAttributeProvider,
 2020        IPropertyInfoProvider propertyInfoProvider,
 2021        IAttributeCriteriaChecker attributeCriteriaChecker)
 22    {
 2023        _metadataSourceChecker = Guard.Against.Null(metadataSourceChecker);
 2024        _attributePropertyMetadataBuilder = Guard.Against.Null(attributePropertyMetadataBuilder);
 2025        _strainerAttributeProvider = Guard.Against.Null(strainerAttributeProvider);
 2026        _propertyInfoProvider = Guard.Against.Null(propertyInfoProvider);
 2027        _propertyMetadataDictionaryProvider = Guard.Against.Null(propertyMetadataDictionaryProvider);
 2028        _attributeCriteriaChecker = Guard.Against.Null(attributeCriteriaChecker);
 2029    }
 30
 31    public IPropertyMetadata? GetDefaultMetadataFromObjectAttribute(Type modelType)
 32    {
 333        Guard.Against.Null(modelType);
 34
 335        if (!IsMetadataSourceEnabled(MetadataSourceType.ObjectAttributes))
 36        {
 137            return null;
 38        }
 39
 240        var currentType = modelType;
 41
 42        do
 43        {
 244            var attribute = _strainerAttributeProvider.GetObjectAttribute(currentType);
 45
 246            if (attribute != null && attribute.DefaultSortingPropertyName != null)
 47            {
 248                var propertyInfo = _propertyInfoProvider.GetPropertyInfo(modelType, attribute.DefaultSortingPropertyName
 249                if (propertyInfo == null)
 50                {
 151                    throw new InvalidOperationException(
 152                        $"Could not find property {attribute.DefaultSortingPropertyName} " +
 153                        $"in type {modelType.FullName} marked as its default " +
 154                        $"sorting property. Ensure that such property exists in " +
 155                        $"{modelType.FullName} and it's accessible.");
 56                }
 57
 158                return _attributePropertyMetadataBuilder.BuildDefaultMetadata(attribute, propertyInfo);
 59            }
 60
 061            currentType = currentType.BaseType;
 62
 63        }
 064        while (currentType != typeof(object) && currentType != typeof(ValueType));
 65
 066        return null;
 67    }
 68
 69    public IPropertyMetadata? GetDefaultMetadataFromPropertyAttribute(Type modelType)
 70    {
 371        Guard.Against.Null(modelType);
 72
 373        if (!IsMetadataSourceEnabled(MetadataSourceType.PropertyAttributes))
 74        {
 175            return null;
 76        }
 77
 278        var attribute = _propertyInfoProvider
 279            .GetPropertyInfos(modelType)
 280            .Select(propertyInfo => _strainerAttributeProvider.GetPropertyAttribute(propertyInfo))
 481            .FirstOrDefault(attribute => attribute is not null && attribute.IsDefaultSorting);
 82
 283        if (attribute != null)
 84        {
 285            if (!attribute.IsSortable)
 86            {
 187                throw new InvalidOperationException(
 188                    $"Property {attribute.PropertyInfo?.Name ?? attribute.Name} " +
 189                    $"on {attribute.PropertyInfo?.DeclaringType?.FullName} " +
 190                    $"is declared as {nameof(IPropertyMetadata.IsDefaultSorting)} " +
 191                    $"but not as {nameof(IPropertyMetadata.IsSortable)}. " +
 192                    $"Set the {nameof(IPropertyMetadata.IsSortable)} to true " +
 193                    $"in order to use the property as a default sortable property.");
 94            }
 95        }
 96
 197        return attribute;
 98    }
 99
 100    public IReadOnlyDictionary<Type, IReadOnlyDictionary<string, IPropertyMetadata>> GetMetadataDictionaryFromObjectAttr
 101        ICollection<Type> types)
 102    {
 1103        Guard.Against.Null(types);
 104
 1105        if (!IsMetadataSourceEnabled(MetadataSourceType.ObjectAttributes))
 106        {
 0107            return new Dictionary<Type, IReadOnlyDictionary<string, IPropertyMetadata>>().ToReadOnly();
 108        }
 109
 1110        return types
 2111            .Select(type => new
 2112            {
 2113                Type = type,
 2114                Attribute = _strainerAttributeProvider.GetObjectAttribute(type),
 2115            })
 2116            .Where(x => x.Attribute != null)
 1117            .Select(x => new
 1118            {
 1119                x.Type,
 1120                Metadatas = _propertyMetadataDictionaryProvider.GetMetadata(x.Type, x.Attribute!),
 1121            })
 2122            .ToDictionary(x => x.Type, x => x.Metadatas)
 1123            .ToReadOnly();
 124    }
 125
 126    public IReadOnlyDictionary<Type, IReadOnlyDictionary<string, IPropertyMetadata>> GetMetadataDictionaryFromPropertyAt
 127        ICollection<Type> types)
 128    {
 1129        Guard.Against.Null(types);
 130
 1131        if (!IsMetadataSourceEnabled(MetadataSourceType.ObjectAttributes))
 132        {
 0133            return new Dictionary<Type, IReadOnlyDictionary<string, IPropertyMetadata>>().ToReadOnly();
 134        }
 135
 1136        return types
 2137            .Select(type => new
 2138            {
 2139                Type = type,
 2140                Attributes = _propertyMetadataDictionaryProvider.GetMetadata(type),
 2141            })
 2142            .Where(x => x.Attributes.Any())
 2143            .ToDictionary(x => x.Type, x => x.Attributes)
 1144            .ToReadOnly();
 145    }
 146
 147    public IPropertyMetadata? GetMetadataFromObjectAttribute(
 148        Type modelType,
 149        bool isSortableRequired,
 150        bool isFilterableRequired,
 151        string name)
 152    {
 0153        Guard.Against.Null(modelType);
 0154        Guard.Against.NullOrWhiteSpace(name);
 155
 0156        if (!IsMetadataSourceEnabled(MetadataSourceType.ObjectAttributes))
 157        {
 0158            return null;
 159        }
 160
 0161        var currentType = modelType;
 162
 163        do
 164        {
 0165            var attribute = _strainerAttributeProvider.GetObjectAttribute(currentType);
 0166            var propertyInfo = _propertyInfoProvider.GetPropertyInfo(currentType, name);
 0167            var isMatching = _attributeCriteriaChecker.CheckIfObjectAttributeIsMatching(
 0168                attribute,
 0169                propertyInfo,
 0170                isSortableRequired,
 0171                isFilterableRequired);
 172
 0173            if (isMatching && attribute is not null && propertyInfo is not null)
 174            {
 0175                return _attributePropertyMetadataBuilder.BuildDefaultMetadataForProperty(attribute, propertyInfo);
 176            }
 177
 0178            currentType = currentType.BaseType;
 179
 180        }
 0181        while (currentType != typeof(object) && currentType != typeof(ValueType));
 182
 0183        return null;
 184    }
 185
 186    public IPropertyMetadata? GetMetadataFromPropertyAttribute(
 187        Type modelType,
 188        bool isSortableRequired,
 189        bool isFilterableRequired,
 190        string name)
 191    {
 4192        Guard.Against.Null(modelType);
 4193        Guard.Against.NullOrWhiteSpace(name);
 194
 4195        if (!IsMetadataSourceEnabled(MetadataSourceType.PropertyAttributes))
 196        {
 1197            return null;
 198        }
 199
 3200        var keyValue = _propertyInfoProvider
 3201            .GetPropertyInfos(modelType)
 2202            .Select(propertyInfo => new
 2203            {
 2204                propertyInfo,
 2205                attribute = _strainerAttributeProvider.GetPropertyAttribute(propertyInfo),
 2206            })
 3207            .FirstOrDefault(x =>
 3208            {
 2209                var propertyInfo = x.propertyInfo;
 2210                var attribute = x.attribute;
 3211
 2212                return _attributeCriteriaChecker.CheckIfPropertyAttributeIsMatching(
 2213                    attribute,
 2214                    propertyInfo,
 2215                    isSortableRequired,
 2216                    isFilterableRequired,
 2217                    name);
 3218            });
 219
 3220        return keyValue?.attribute;
 221    }
 222
 223    public IReadOnlyList<IPropertyMetadata>? GetMetadataFromObjectAttribute(Type modelType)
 224    {
 0225        Guard.Against.Null(modelType);
 226
 0227        if (!IsMetadataSourceEnabled(MetadataSourceType.ObjectAttributes))
 228        {
 0229            return null;
 230        }
 231
 0232        var currentType = modelType;
 233
 234        do
 235        {
 0236            var attribute = _strainerAttributeProvider.GetObjectAttribute(currentType);
 0237            if (attribute != null)
 238            {
 0239                return _propertyInfoProvider.GetPropertyInfos(currentType)
 0240                    .Select(propertyInfo => _attributePropertyMetadataBuilder.BuildDefaultMetadataForProperty(attribute,
 0241                    .ToList()
 0242                    .AsReadOnly();
 243            }
 244
 0245            currentType = currentType.BaseType;
 246        }
 0247        while (currentType != typeof(object) && currentType != typeof(ValueType));
 248
 0249        return null;
 250    }
 251
 252    public IReadOnlyList<IPropertyMetadata>? GetMetadataFromPropertyAttribute(Type modelType)
 253    {
 0254        Guard.Against.Null(modelType);
 255
 0256        if (!IsMetadataSourceEnabled(MetadataSourceType.PropertyAttributes))
 257        {
 0258            return null;
 259        }
 260
 0261        var metadata = _propertyInfoProvider
 0262            .GetPropertyInfos(modelType)
 0263            .Select(propertyInfo => _strainerAttributeProvider.GetPropertyAttribute(propertyInfo))
 0264            .Where(attribute => attribute != null)
 0265            .Cast<IPropertyMetadata>()
 0266            .ToList()
 0267            .AsReadOnly();
 268
 0269        return metadata.Any()
 0270            ? metadata
 0271            : null;
 272    }
 273
 274    private bool IsMetadataSourceEnabled(MetadataSourceType metadataSourceType)
 275    {
 12276        return _metadataSourceChecker.IsMetadataSourceEnabled(metadataSourceType);
 277    }
 278}