изменения пользовательских атрибутов в .NET 4 - PullRequest
1 голос
/ 01 июня 2010

Я недавно обновил проект C # с .NET 3.5 до .NET 4. У меня есть метод, который извлекает все методы тестирования MSTest из заданного списка MethodBase экземпляров. Его тело выглядит так:

return null == methods || methods.Count() == 0
    ? null
    : from method in methods
      let testAttribute = Attribute.GetCustomAttribute(method,
          typeof(TestMethodAttribute))
      where null != testAttribute
      select method;

Это работало в .NET 3.5, но после обновления моих проектов до .NET 4 этот код всегда возвращает пустой список, даже если ему дан список методов, содержащих метод, помеченный [TestMethod]. Что-то изменилось с пользовательскими атрибутами в .NET 4?

Отладка, я обнаружил, что результаты GetCustomAttributesData() в тестовом методе дают список из двух CustomAttributeData, которые описаны в окне 'Locals' в Visual Studio 2010 как:

  1. Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute("myDLL.dll")
  2. Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute() - это то, что я ищу

Когда я вызываю GetType() в этом втором CustomAttributeData экземпляре, я получаю {Name = "CustomAttributeData" FullName = "System.Reflection.CustomAttributeData"} System.Type {System.RuntimeType}. Как я могу получить TestMethodAttribute из CustomAttributeData, чтобы я мог извлечь методы тестирования из списка MethodBase s?

Ответы [ 2 ]

2 голосов
/ 01 июня 2010

Глупая ошибка с моей стороны: мой метод извлечения тестовых методов был в проекте библиотеки классов, который ссылался на Microsoft.VisualStudio.QualityTools.UnitTestFramework, чтобы он мог искать TestMethodAttribute в качестве пользовательского атрибута. Когда я обновил свое Решение с VS 2008 до VS 2010, процесс преобразования автоматически обновил ссылки из Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version = 9.0.0.0 до Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version = 10.0.0.0 в моих тестовых проектах. Однако он не обновил ссылку в моем проекте библиотеки классов, так что он все еще указывал на старую ссылку UnitTestFramework. Когда я изменил этот проект так, чтобы он указывал на библиотеку 10.0.0.0, мой код, приведенный ниже, работал как положено:

return null == methods || methods.Count() == 0
    ? null
    : from method in methods
      let testAttribute = Attribute.GetCustomAttribute(method,
          typeof(TestMethodAttribute))
      where null != testAttribute
      select method;

Кроме того, код Джон предположил, что также сработало, как только я обновил ссылку.

2 голосов
/ 01 июня 2010

Вы пробовали использовать

method.GetCustomAttributes(typeof(TestMethodAttribute), false)

вместо этого? Запрос цели для пользовательских атрибутов обычно был способом получения их.

Вот поспешный пример:

using System;
using System.Linq;

[AttributeUsage(AttributeTargets.All)]
public class FooAttribute : Attribute {}

class Test
{
    static void Main()
    {
        var query = typeof(Test).GetMethods()
            .Where(method => method.GetCustomAttributes(
                              typeof(FooAttribute), false).Length != 0);

        foreach (var method in query)
        {
            Console.WriteLine(method);
        }
    }

    [Foo]
    public static void MethodWithAttribute1() {}

    [Foo]
    public static void MethodWithAttribute2() {}

    public static void MethodWithoutAttribute() {}

}
...