4

using the FastMember library from NuGet, I am able to find all the members of a type that are decorated with a particular attribute, using this code:

var accessor = TypeAccessor.Create(typeof (MyData));
var decoratedMembers = accessor.GetMembers().Where(x=>x.IsDefined(typeof(MyDecorationAttribute));

That's all very well and good, but I need to now be able to get the specific instance of MyDecorationAttribute for each of the members in decoratedMembers MemberSet and as far as I can see there isn't a way to do that.

Am I missing something? Perhaps there's a different library that I should be using to get the attribute data per member, or is stock Reflection the way to go in this case.

Ralph Shillington
  • 20,718
  • 23
  • 91
  • 154
  • 2
    *attribute* handling simply isn't a core part of what that library is about... if it isn't exposed, then regular reflection may be your best option – Marc Gravell Feb 24 '14 at 07:28
  • 1
    @MarcGravell - Understood. It just seemed so close with the IsDefined function sitting right in front of me. None the less, it's a great library. – Ralph Shillington Feb 24 '14 at 12:55
  • 1
    I wish this feature could be added to the library, it would make it the defacto solution for many scenarios. – MaYaN Jun 26 '15 at 18:06

2 Answers2

4

First and foremost - Marc, thank you very much for an AWESOME library!

Second, please forgive me Marc, for I am about to sin...

I have had the same problem - a desire to access a MemberInfo about the member, but library lets me "sniff" it, but not to access it.

With a bit of help from http://www.codeproject.com/Articles/80343/Accessing-private-members.aspx

public static class SillyMemberExtensions
{
    public static T GetPrivateField<T>(this object obj, string name)
    {
        BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
        Type type = obj.GetType();
        FieldInfo field = type.GetField(name, flags);
        return (T)field.GetValue(obj);
    }

    public static T GetPrivateProperty<T>(this object obj, string name)
    {
        BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
        Type type = obj.GetType();
        PropertyInfo field = type.GetProperty(name, flags);
        return (T)field.GetValue(obj, null);
    }

    public static MemberInfo GetMemberInfo(this FastMember.Member member)
    {
        return GetPrivateField<MemberInfo>(member, "member");
    }

    public static T GetMemberAttribute<T>(this FastMember.Member member) where T : Attribute
    {
        return GetPrivateField<MemberInfo>(member, "member").GetCustomAttribute<T>();
    }
}

Usage:

if (m.IsDefined(typeof(MyCustomAttribute)))
{
    var attr = m.GetMemberAttribute<MyCustomAttribute>();
    if (attr.SomeCustomParameterInTheAttribute >= 10)
        return "More than 10";
}
Andrey Tch.
  • 91
  • 2
  • 3
  • use refelection to access private field of FastMember combine the disavantage of reflection (one person would otherwise use it directly to read attribute) with the disavantage to be entangled with internal structure of an external library. A no-no solution IMHO – Skary Aug 05 '21 at 14:50
0

This is not alternative to fast-member but, it has Private Member support, Attribute support and Caching. Here is SlowMember

Usage:

var reflectionService = new ReflectionService();
var description = reflectionService.GetObjectDescription(_complexClass, true);
var attributeDescription = description.MemberDescriptions
            .FirstOrDefault(f => f.Name == "Text")
            .AttributeDescriptions.FirstOrDefault(ad => ad.Name == "Required");

Github Repository: https://github.com/efaruk/slow-member

efaruk
  • 882
  • 9
  • 25