Search code examples
c#reflectioncustom-attributesmetadatatype

MetadataType and Attribute.IsDefined


I am using a database first approach and have a class SalesWallboard mapped to the database table.

SalesWallboard.cs:

namespace Wallboards.DAL.SchnellDb
{
    public partial class SalesWallboard
    {
        public int Id { get; set; }
        public string StaffName { get; set; }
        ...
    }
}

I have created a MetadataType class for this to apply custom attributes

SalesWallboardModel.cs

namespace Wallboards.DAL.SchnellDb
{
    [MetadataType (typeof(SalesWallboardModel))]
    public partial class SalesWallboard
    {

    }

    public class SalesWallboardModel
    {
        [UpdateFromEclipse]
        public string StaffName { get; set; }
        ...
    }
}

But in my code, when I check it using Attribute.IsDefined, it always throws false.

Code

var salesWallboardColumns = typeof(SalesWallboard).GetProperties();
foreach (var column in salesWallboardColumns)
{
    if (Attribute.IsDefined(column, typeof(UpdateFromEclipse))) //returns false
    {
        ...
    }
}

I have checked the answer given here. But I don't understand the example. Can someone please simplify this for me?


Solution

  • I would like to thank @elgonzo and @thehennyy for their comments and correcting my understanding with reflection.

    I found what I was looking for here. But I had to make a few modifications shown below.

    I created a method PropertyHasAttribute

    private static bool PropertyHasAttribute<T>(string propertyName, Type attributeType)
    {
        MetadataTypeAttribute att = (MetadataTypeAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(MetadataTypeAttribute));
        if (att != null)
        {
            foreach (var prop in GetType(att.MetadataClassType.UnderlyingSystemType.FullName).GetProperties())
            {
                if (propertyName.ToLower() == prop.Name.ToLower() && Attribute.IsDefined(prop, attributeType))
                    return true;
            }
        }
        return false;
    }
    

    I also got help from here because my type was in a different assembly.

    Method GetType

    public static Type GetType(string typeName)
    {
        var type = Type.GetType(typeName);
        if (type != null) return type;
        foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
        {
            type = a.GetType(typeName);
            if (type != null)
                return type;
        }
        return null;
    }
    

    Then used it in my code like so

    Code

    var salesWallboardColumns = typeof(SalesWallboard).GetProperties();
    foreach (var column in salesWallboardColumns)
    {
        var columnName = column.Name;
        if (PropertyHasAttribute<SalesWallboard>(columnName, typeof(UpdateFromEclipse)))
        {
            ...
        }
    }