< Summary

Information
Class: Fluorite.Strainer.Services.Metadata.FluentApi.FluentApiMetadataProvider
Assembly: Fluorite.Strainer
File(s): /builds/fluorite/strainer/src/Strainer/Services/Metadata/FluentApi/FluentApiMetadataProvider.cs
Line coverage
100%
Covered lines: 73
Uncovered lines: 0
Coverable lines: 73
Total lines: 169
Line coverage: 100%
Branch coverage
100%
Covered branches: 44
Total branches: 44
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetAllPropertyMetadata()100%22100%
GetDefaultMetadata(...)100%66100%
GetPropertyMetadata(...)100%2828100%
GetPropertyMetadatas(...)100%66100%
BuildMetadataKeyValuePair(...)100%22100%
GetPropertyMetadatasFromObjectMetadata(...)100%11100%
IsFluentApiEnabled()100%11100%
IsMetadataSourceEnabled(...)100%11100%

File(s)

/builds/fluorite/strainer/src/Strainer/Services/Metadata/FluentApi/FluentApiMetadataProvider.cs

#LineLine coverage
 1using Fluorite.Extensions;
 2using Fluorite.Strainer.Models.Metadata;
 3using Fluorite.Strainer.Services.Configuration;
 4
 5namespace Fluorite.Strainer.Services.Metadata.FluentApi;
 6
 7public class FluentApiMetadataProvider : IMetadataProvider
 8{
 9    private readonly IStrainerOptionsProvider _strainerOptionsProvider;
 10    private readonly IConfigurationMetadataProvider _metadataProvider;
 11    private readonly IFluentApiPropertyMetadataBuilder _propertyMetadataBuilder;
 12    private readonly IPropertyInfoProvider _propertyInfoProvider;
 13
 6014    public FluentApiMetadataProvider(
 6015        IStrainerOptionsProvider strainerOptionsProvider,
 6016        IConfigurationMetadataProvider metadataProvider,
 6017        IPropertyInfoProvider propertyInfoProvider,
 6018        IFluentApiPropertyMetadataBuilder propertyMetadataBuilder)
 19    {
 6020        _strainerOptionsProvider = Guard.Against.Null(strainerOptionsProvider);
 6021        _metadataProvider = Guard.Against.Null(metadataProvider);
 6022        _propertyInfoProvider = Guard.Against.Null(propertyInfoProvider);
 6023        _propertyMetadataBuilder = Guard.Against.Null(propertyMetadataBuilder);
 6024    }
 25
 26    public IReadOnlyDictionary<Type, IReadOnlyDictionary<string, IPropertyMetadata>>? GetAllPropertyMetadata()
 27    {
 428        if (!IsFluentApiEnabled())
 29        {
 130            return null;
 31        }
 32
 333        var objectMetadata = _metadataProvider.GetObjectMetadata();
 334        var propertyMetadata = _metadataProvider.GetPropertyMetadata();
 35
 336        return propertyMetadata
 337            .Keys
 338            .Union(objectMetadata.Keys)
 239            .Select(type => (type, BuildMetadataKeyValuePair(type, objectMetadata, propertyMetadata)))
 440            .ToDictionary(tuple => tuple.type, tuple => tuple.Item2)
 341            .ToReadOnly();
 42    }
 43
 44    public IPropertyMetadata? GetDefaultMetadata(Type modelType)
 45    {
 1046        Guard.Against.Null(modelType);
 47
 1048        if (!IsFluentApiEnabled())
 49        {
 150            return null;
 51        }
 52
 953        _metadataProvider.GetDefaultMetadata().TryGetValue(modelType, out var propertyMetadata);
 54
 955        if (propertyMetadata == null)
 56        {
 857            if (_metadataProvider.GetObjectMetadata().TryGetValue(modelType, out var objectMetadata))
 58            {
 759                propertyMetadata = _propertyMetadataBuilder.BuildDefaultMetadata(objectMetadata);
 60            }
 61        }
 62
 963        return propertyMetadata;
 64    }
 65
 66    public IPropertyMetadata? GetPropertyMetadata(
 67        Type modelType,
 68        bool isSortableRequired,
 69        bool isFilterableRequired,
 70        string name)
 71    {
 4072        Guard.Against.Null(modelType);
 4073        Guard.Against.NullOrWhiteSpace(name);
 74
 4075        if (!IsFluentApiEnabled())
 76        {
 177            return null;
 78        }
 79
 3980        if (_metadataProvider.GetPropertyMetadata().TryGetValue(modelType, out var propertyMetadatas))
 81        {
 1782            var propertyMetadata = propertyMetadatas
 1783                .Where(pair =>
 1784                {
 1785                    return pair.Key.Equals(name)
 1786                        && (!isSortableRequired || pair.Value.IsSortable)
 1787                        && (!isFilterableRequired || pair.Value.IsFilterable);
 1788                })
 1789                .FirstOrDefault().Value;
 90
 1791            return propertyMetadata;
 92        }
 93
 2294        if (_metadataProvider.GetObjectMetadata().TryGetValue(modelType, out var objectMetadata))
 95        {
 2196            if (((isFilterableRequired && objectMetadata.IsFilterable) || (!isFilterableRequired))
 2197                && ((isSortableRequired && objectMetadata.IsSortable) || (!isSortableRequired)))
 98            {
 999                var propertyInfo = _propertyInfoProvider.GetPropertyInfo(modelType, name);
 9100                if (propertyInfo is not null)
 101                {
 9102                    return _propertyMetadataBuilder.BuildMetadataForProperty(objectMetadata, propertyInfo);
 103                }
 104            }
 105        }
 106
 13107        return null;
 108    }
 109
 110    public IReadOnlyList<IPropertyMetadata>? GetPropertyMetadatas(Type modelType)
 111    {
 4112        Guard.Against.Null(modelType);
 113
 4114        if (!IsFluentApiEnabled())
 115        {
 1116            return null;
 117        }
 118
 3119        if (_metadataProvider.GetPropertyMetadata().TryGetValue(modelType, out var metadatas))
 120        {
 1121            return metadatas.Values.ToList().AsReadOnly();
 122        }
 123
 2124        if (_metadataProvider.GetObjectMetadata().TryGetValue(modelType, out var objectMetadata))
 125        {
 1126            return _propertyInfoProvider.GetPropertyInfos(modelType)
 1127                .Select(p => _propertyMetadataBuilder.BuildMetadataForProperty(objectMetadata, p))
 1128                .ToList();
 129        }
 130
 1131        return null;
 132    }
 133
 134    private IReadOnlyDictionary<string, IPropertyMetadata> BuildMetadataKeyValuePair(
 135        Type type,
 136        IReadOnlyDictionary<Type, IObjectMetadata> objectMetadata,
 137        IReadOnlyDictionary<Type, IReadOnlyDictionary<string, IPropertyMetadata>> propertyMetadata)
 138    {
 139        // TODO: Shouldn't property metadata override object metadata, but still be returned?
 140        // So type-wide config is set with object call, but property call overrides that for some special case?
 2141        if (propertyMetadata.TryGetValue(type, out var metadatas))
 142        {
 1143            return metadatas;
 144        }
 145
 1146        var objectMetadataForType = objectMetadata[type];
 147
 1148        return GetPropertyMetadatasFromObjectMetadata(type, objectMetadataForType);
 149    }
 150
 151    private IReadOnlyDictionary<string, IPropertyMetadata> GetPropertyMetadatasFromObjectMetadata(Type type, IObjectMeta
 152    {
 1153        return _propertyInfoProvider
 1154            .GetPropertyInfos(type)
 1155            .Select(propertyInfo => _propertyMetadataBuilder.BuildMetadataForProperty(objectMetadata, propertyInfo))
 2156            .ToDictionary(p => p.Name, p => p)
 1157            .ToReadOnlyDictionary();
 158    }
 159
 58160    private bool IsFluentApiEnabled() => IsMetadataSourceEnabled(MetadataSourceType.FluentApi);
 161
 162    private bool IsMetadataSourceEnabled(MetadataSourceType metadataSourceType)
 163    {
 58164        return _strainerOptionsProvider
 58165            .GetStrainerOptions()
 58166            .MetadataSourceType
 58167            .HasFlag(metadataSourceType);
 168    }
 169}