Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I filter out <>c_DisplayClass types when going through types via reflection?

Tags:

I am trying to create a unit test that makes sure all of my business classes (I call them command and query classes) can be resolved with Windsor. I have the following unit test:

    [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);         }     } 

This fails with the following exception:

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

I understand that <>c__DisplayClass0 types are due to Linq being compiled, but how can I filter out these types without hardcoding the name in my Linq query?

like image 893
KallDrexx Avatar asked Jun 28 '11 22:06

KallDrexx


People also ask

Which of these can be achieved by reflection in C#?

You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them.

What is System reflection?

Reflection is the process of describing the metadata of types, methods and fields in a code. The namespace System.Reflection enables you to obtain data about the loaded assemblies, the elements within them like classes, methods and value types. Some of the commonly used classes of System.Reflection are: Class.

What is C# reflection?

Reflection in C# is used to retrieve metadata on types at runtime. In other words, you can use reflection to inspect metadata of the types in your program dynamically -- you can retrieve information on the loaded assemblies and the types defined in them.


2 Answers

I would check each Type for the System.Runtime.CompilerServices.CompilerGeneratedAttribute that is put on these.

You can use Type.IsDefined, so the code would look something like this:

foreach (Type type in classTypes) {    if (type.IsDefined (typeof (CompilerGeneratedAttribute), false))       continue;     // use type... } 
like image 178
agent-j Avatar answered Sep 19 '22 05:09

agent-j


Apparently nested classes do not get the [CompilerGenerated] attribute applied to them.

I whipped up this simple method to deal with this scenario.

bool IsCompilerGenerated(Type t) {     if (t == null)         return false;      return t.IsDefined(typeof(CompilerGeneratedAttribute), false)         || IsCompilerGenerated(t.DeclaringType); } 

A class that exhibits this behaviour would look like this:

class SomeClass {     void CreatesADisplayClass() {         var message = "foo";          Action outputFunc = () => Trace.Write(message);          Action wheelsWithinWheels = () =>         {             var other = "bar";              Action wheel = () => Trace.WriteLine(message + " " + other);         };     } } 
like image 24
Cameron MacFarland Avatar answered Sep 22 '22 05:09

Cameron MacFarland