当通过反射浏览类型时,如何过滤掉<> c_DisplayClass类型?

Kal*_*exx 22 c# reflection

我正在尝试创建一个单元测试,以确保我的所有业务类(我称之为命令和查询类)可以使用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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

这失败,出现以下异常:

No component for supporting the service MyApp.DomainModel.Queries.Organizations.OrganizationByRegistrationTokenQuery+<>c__DisplayClass0 was found
Run Code Online (Sandbox Code Playgroud)

我知道<>c__DisplayClass0类型是由于Linq被编译,但是如何在我的Linq查询中没有硬编码名称的情况下过滤掉这些类型?

age*_*t-j 27

我会检查每个Type上的System.Runtime.CompilerServices.CompilerGeneratedAttribute.

您可以使用Type.IsDefined,因此代码看起来像这样:

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

   // use type...
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`type.IsDefined`来简化生活. (5认同)

Cam*_*and 14

显然,嵌套类不会将[CompilerGenerated]属性应用于它们.

我掀起了这个简单的方法来处理这种情况.

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

    return t.IsDefined(typeof(CompilerGeneratedAttribute), false)
        || IsCompilerGenerated(t.DeclaringType);
}
Run Code Online (Sandbox Code Playgroud)

展示此行为的类将如下所示:

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

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

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

            Action wheel = () => Trace.WriteLine(message + " " + other);
        };
    }
}
Run Code Online (Sandbox Code Playgroud)