mgravell / fast-member

Automatically exported from code.google.com/p/fast-member
Apache License 2.0
1.02k stars 137 forks source link

[Feature Request] ObjectReader.Create() option to filter out properties with certain Attribute #78

Open ThaDaVos opened 5 years ago

ThaDaVos commented 5 years ago

It would be great if somehow properties could be ignored which have a certain Attribute currently doing it as follows to filter out all properties with the NotMappedAttribute but seems a bit slow:

var accessor = TypeAccessor.Create(typeof(T));
var fields = accessor.GetMembers().Where(x => !x.IsDefined(typeof(NotMappedAttribute))).Select(x => x.Name).ToArray();
using var reader = ObjectReader.Create(data, fields);
cajuncoding commented 2 years ago

Seems like some caching on the fields would solve the slow issue?

Here's a Helper class that wraps it up with a cache.... can't use a Custom Extension because TypeAccessor is abstract, doesn't use Generics, and doesn't provide public access to the internal Type being handled by FastMember.... but the helper is just as easy to consume...

public static class TypeAccessorHelpers
{
    private static readonly ConcurrentDictionary<Type, Lazy<string[]>> _accessorFieldsLazyCache = new();

    public static string[] GetOnlyMappedFieldsForType<T>()
    {
        var objectType = typeof(T);
        return _accessorFieldsLazyCache.GetOrAdd(objectType, new Lazy<string[]>(() =>
        {
            var accessor = TypeAccessor.Create(objectType);
            return accessor.GetMembers()
                .Where(x => !x.IsDefined(typeof(NotMappedAttribute)))
                .Select(x => x.Name)
                .ToArray();
        }))?.Value;
    }
}

Usage:

var fields = TypeAccessorHelpers.GetOnlyMappedFieldsForType<T>();
using var reader = ObjectReader.Create(data, fields);