Как отфильтровать типы <> c_DisplayClass при прохождении типов через отражение? - PullRequest
22 голосов
/ 29 июня 2011

Я пытаюсь создать модульный тест, который гарантирует, что все мои бизнес-классы (я называю их классами команд и запросов) могут быть разрешены с помощью Windsor. У меня есть следующий модульный тест:

    [TestMethod]
    public void Windsor_Can_Resolve_All_Command_And_Query_Classes()
    {
        // Setup
        Assembly asm = Assembly.GetAssembly(typeof(IUnitOfWork));
        IList<Type> classTypes = asm.GetTypes()
                                    .Where(x => x.Namespace.StartsWith("MyApp.DomainModel.Commands") || x.Namespace.StartsWith("MyApp.DomainModel.Queries"))
                                    .Where(x => x.IsClass)
                                    .ToList();

        IWindsorContainer container = new WindsorContainer();
        container.Kernel.ComponentModelBuilder.AddContributor(new SingletonLifestyleEqualizer());
        container.Install(FromAssembly.Containing<HomeController>());

        // Act
        foreach (Type t in classTypes)
        {
            container.Resolve(t);
        }
    }

Это происходит со следующим исключением:

No component for supporting the service MyApp.DomainModel.Queries.Organizations.OrganizationByRegistrationTokenQuery+<>c__DisplayClass0 was found

Я понимаю, что <>c__DisplayClass0 типы связаны с компиляцией Linq, но как я могу отфильтровать эти типы без жесткого кодирования имени в моем запросе Linq?

Ответы [ 3 ]

27 голосов
/ 29 июня 2011

Я бы проверял каждый тип для System.Runtime.CompilerServices.CompilerGeneratedAttribute , который надевается на них.

Вы можете использовать Type.IsDefined , поэтомукод будет выглядеть примерно так:

foreach (Type type in classTypes)
{
   if (type.IsDefined (typeof (CompilerGeneratedAttribute), false))
      continue;

   // use type...
}
14 голосов
/ 07 августа 2012

По-видимому, к вложенным классам не применяется атрибут [CompilerGenerated].

Я выбрал этот простой метод для решения этого сценария.

bool IsCompilerGenerated(Type t) {
    if (t == null)
        return false;

    return t.IsDefined(typeof(CompilerGeneratedAttribute), false)
        || IsCompilerGenerated(t.DeclaringType);
}

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

class SomeClass {
    void CreatesADisplayClass() {
        var message = "foo";

        Action outputFunc = () => Trace.Write(message);

        Action wheelsWithinWheels = () =>
        {
            var other = "bar";

            Action wheel = () => Trace.WriteLine(message + " " + other);
        };
    }
}
4 голосов
/ 29 июня 2011

Проверьте наличие атрибута [CompilerGenerated].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...