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?
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.
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.
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.
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... }
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); }; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With