Отражение, получить атрибуты DataAnnotation из класса друзей - PullRequest
4 голосов
/ 10 апреля 2010

Мне нужно проверить, имеет ли свойство определенный атрибут, определенный в его классе собеседника:

[MetadataType(typeof(Metadata))]
public sealed partial class Address
{
    private sealed class Metadata
    {
        [Required]
        public string Address1 { get; set; }

        [Required]
        public string Zip { get; set; }
    }
}

Как проверить, какие свойства определили атрибут Required?

Спасибо.

Ответы [ 3 ]

8 голосов
/ 10 апреля 2010

Это можно сделать, используя исследование вложенных типов:

public IEnumerable<PropertyInfo> GetRequiredProperties()
{
    var nestedTypes = typeof(Address).GetNestedTypes(BindingFlags.NonPublic);

    var nestedType = nestedTypes.First(); // It can be done for all types

    var requiredProperties =
        nestedType.GetProperties()
            .Where(property => 
                           property.IsDefined(typeof(RequiredAttribute), false));

    return requiredProperties;
}

Пример использования:

[Test]
public void Example()
{
    var requiredProperties = GetRequiredProperties();
    var propertiesNames = requiredProperties.Select(property => property.Name);

    Assert.That(propertiesNames, Is.EquivalentTo(new[] { "Address1", "Zip" }));
}
0 голосов
/ 11 апреля 2010

Вот мое решение usinjg AssociatedMetadataTypeTypeDescriptionProvider:

var entity = CreateAddress();
var type = entity.GetType();
var metadata = (MetadataTypeAttribute)type.GetCustomAttributes(typeof(MetadataTypeAttribute), true).FirstOrDefault();
var properties = new AssociatedMetadataTypeTypeDescriptionProvider(type, metadata.MetadataClassType).GetTypeDescriptor(type).GetProperties();
bool hasAttribute = HasMetadataPropertyAttribute(properties, "Name", typeof(RequiredAttribute));

private static bool HasMetadataPropertyAttribute(PropertyDescriptorCollection properties, string name, Type attributeType)
{
    var property = properties[name];
    if ( property == null )
        return false;

    var hasAttribute = proeprty.Attributes.Cast<object>().Any(a => a.GetType() == attributeType);
    return hasAttribute;
}
0 голосов
/ 10 апреля 2010

Хотя это и менее элегантно, чем решение Елисея, но оно также работает:)

Ваш атрибут:

[AttributeUsage(AttributeTargets.All, AllowMultiple=false)]
class RequiredAttribute : System.Attribute
{
    public string Name {get; set; }

    public RequiredAttribute(string name)
    {
        this.Name = name;
    }

    public RequiredAttribute()
    {
        this.Name = "";
    }
}

Некоторые классы:

class Class1
{
    [Required]
    public string Address1 { get; set; }

    public string Address2 { get; set; }

    [Required]
    public string Address3 { get; set; }
}

Использование:

Class1 c = new Class1();
RequiredAttribute ra = new RequiredAttribute();

Type class1Type = c.GetType();
PropertyInfo[] propInfoList = class1Type.GetProperties();
foreach (PropertyInfo p in propInfoList)
{
    object[] a = p.GetCustomAttributes(true);
    foreach (object o in a)
    {
        if (o.GetType().Equals(ra.GetType()))
        {
            richTextBox1.AppendText(p.Name + " ");
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...