2013-01-21 15 views
9

Próbuję napisać metodę, która znajduje wszystkie typy w zespole z określonym atrybut niestandardowy. Muszę również być w stanie podać wartość ciągu, aby dopasować się. Ograniczeniem jest to, że chciałbym móc uruchomić to na dowolnej klasie i zwrócić jakąkolwiek wartość.Dynamicznie uzyskać wartość atrybutu klasy od typu

Na przykład: chciałbym wykonywać połączenia tak

Type tTest = TypeFinder.GetTypesWithAttributeValue(Assembly.Load("MyAssembly"), typeof(DiagnosticTestAttribute), "TestName", "EmailTest"); 

Moja metoda dotąd wygląda następująco:

public static Type GetTypesWithAttributeValue(Assembly aAssembly, Type tAttribute, string sPropertyName, object oValue) 
{ 
    object oReturn = null; 
    foreach (Type type in aAssembly.GetTypes()) 
    { 
     foreach (object oTemp in type.GetCustomAttributes(tAttribute, true)) 
     { 
      //if the attribute we are looking for matches 
      //the value we are looking for, return the current type. 
     } 
    } 
    return typeof(string); //otherwise return a string type 
} 

Moja Atrybut wygląda następująco:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] 
public class DiagnosticTestAttribute : Attribute 
{ 
    private string _sTestName = string.Empty; 

    public string TestName 
    { 
     get { return _sTestName; } 
    } 
    public DiagnosticTest(string sTestName) 
    { 
     _sTestName = sTestName; 
    } 
} 

Dla tych, którzy znają wyrażenia, bardzo chciałbym móc zadzwonić li ke:

TypeFinder.GetTypesWithAttributeValue<DiagnosticTestAttribute>(Assembly.Load("MyAssembly"), x=> x.TestName, "EmailTest"); 

Miejsce, w którym wyrażenie używa mojego rodzaju ogólnego, aby wybrać właściwość, której szukam.

Odpowiedz

13

To powinno działać:

public static Type GetTypeWithAttributeValue<TAttribute>(Assembly aAssembly, Func<TAttribute, object> pred, object oValue) { 
    foreach (Type type in aAssembly.GetTypes()) { 
    foreach (TAttribute oTemp in type.GetCustomAttributes(typeof(TAttribute), true)) { 
     if (Equals(pred(oTemp), oValue)) { 
     return type; 
     } 
    } 
    } 
    return typeof(string); //otherwise return a string type 
} 

Albo nawet ładniejszy:

public static Type GetTypeWithAttributeValue<TAttribute>(Assembly aAssembly, Predicate<TAttribute> pred) { 
    foreach (Type type in aAssembly.GetTypes()) { 
    foreach (TAttribute oTemp in type.GetCustomAttributes(typeof(TAttribute), true)) { 
     if (pred(oTemp)) { 
     return type; 
     } 
    } 
    } 
    return typeof(string); //otherwise return a string type 
} 

ten sposób wywołanie wygląda następująco:

GetTypeWithAttributeValue<DefaultValueAttribute>(Assembly.GetCallingAssembly(), attribute => attribute.Value, 
                "string"); 

i ten odpowiednio:

GetTypeWithAttributeValue<DefaultValueAttribute>(Assembly.GetCallingAssembly(), 
                attribute => attribute.Value == "string"); 
+0

To działało bez zarzutu. Musiałem zmienić montaż, ponieważ nazwałem go innym, ale działa świetnie. Wielkie dzięki. –

+0

jeśli mógłbym dać ci więcej wiary ;-) – Seabizkit

2

Dawno temu stworzyliśmy kilka metod pomocnika wyodrębnić nazwę właściwości z wyrazem,

myślę byłoby przydatna.

public static string Item<TItem, TMember>(this TItem obj, Expression<Func<TItem, TMember>> expression) 
{ 
    if (expression.Body is MemberExpression) 
    { 
     return ((MemberExpression)(expression.Body)).Member.Name; 
    } 
    if (expression.Body is UnaryExpression) 
    { 
     return ((MemberExpression)((UnaryExpression)(expression.Body)).Operand).Member.Name; 
    } 
    if (expression.Body is ParameterExpression) 
    { 
     return expression.Body.Type.Name; 
    } 
    throw new InvalidOperationException(); 
} 

Więcej informacji na stronie this file.

+0

To jest pomocne. Jak tylko mogę wymyślić, jak wyodrębnić wartość z atrybutu klasy instancji, która powinna mi pomóc stworzyć ładny interfejs dla mojej metody. Dzięki! –