In this post we’ll start looking at the structure of the solution for the problem posed in Part 1.
Recall from the previous post that we were wanting to create a library that could iterate over an assembly looking for types with the attribute [MyClassAttribute] and then invoke methods within that class with the attribute [MyMethodAttribute].
Here’s an example of what this class might look like:
[MyClassAttribute] public class MyTestClass { [MyMethodAttribute] public void MyTestMethod() { Console.Writeline("MyTestMethod Called"); } }
Our end goal is to invoke MyTestMethod dynamically, and see the resulting “MyTestMethod Called” rendered to the console window.
So let’s start by looking at a solution that can support this. I’m using Visual Studio 2012:
Image may be NSFW.
Clik here to view.
Technically, we could host all of the code under one project, but I’ve chosen to split it up into the following[1]:
- AttributeDiscovery contains the code that will walk our assembly/class/method walker.
- The rather narcissistically named JamesWisemanAttribute contains code that declares our custom attributes.
- AttributeUser is the class that will use the custom attribute, and as such should be picked up by the attribute discoverer.
- HostConsoleApp is the container app for all of this.
HostConsoleApp will reference all three other assemblies. AttributeUser will reference JamesWisemanAttribute. The other projects will reference nothing other than the Microsoft assemblies required for their execution (such as System.Reflection).
It is of particular importance that AttributeDiscovery references nothing. By doing this we are ensuring that it is loosely bound, and not dependent on any particular attribute or code library. That way we can point it at any assembly searching for any attribute.
Now we’ve defined the structure, in Part 3 we’ll start defining some code for our projects…
[1] Yes, there’s no unit test project. Unit tests are important, and any production-grade code should have a suite of them. This is just a demo, and unit tests would not add to the discussion.