Testing the Application
At this point you can run your application. When you select the
CSharpSnapIn.dll or
Vb2005SnapIn.dll assemblies, you should see the messages displayed via the calls to
MessageBox.Show(), and the ListBox will update with the names of the loaded external modules.
Figure 2 shows one possible run.
 | |
| Figure 2. Loaded Snap-ins: After selecting the CSharpSnapIn and Vb2005SnapIn assemblies, you'll see these items in the "Loaded Snap-ins" ListBox. |
|
 | |
| Figure 3. Invalid File Message: This is the message you'll see if you try to load an external file that doesn't contain a type that implements IAppFunctionality. |
|
|
If you attempt to load any external file that does not contain a type implementing IAppFunctionality, you'll get the message shown in
Figure 3.
Reflecting over Custom Attributes
The final task is to display the metadata provided by the custom
[CompanyInfo] attribute. To do so, update the current implementation of
LoadExternalModule() to call a new helper function named
DisplayCompanyData() before exiting the scope of the conditional block that begins with
if (t != null). The method takes a single System.Type parameter.
private bool LoadExternalModule(string path)
{
...
if (t != null)
{
...
// Show company info.
DisplayCompanyData(theTypes[i]);
}
...
return foundSnapIn;
}
Using the incoming type, simply reflect over the
[CompanyInfo] attribute using the
Type.GetCustomAttributes() method (the Boolean parameter of this method controls whether to also search parent classes for the attribute set):
private void DisplayCompanyData(Type t)
{
// Get all attributes on type.
object[] customAtts = t.GetCustomAttributes(false);
 | |
| Figure 4. Company Info: The DisplayCompanyData() method extracts the metadata from the [CompanyInfo] attribute and displays it in a MessageBox. |
// Show data for any [CompanyInfo] attributes.
foreach (CompanyInfoAttribute c in customAtts)
{
MessageBox.Show(c.Url,
string.Format(
"More info about {0} can be found at",
c.Name));
}
}
Now, when you select an assembly containing a type implementing IAppFunctionality, you'll find the metadata applied by the type's developers to the
[CompanyInfo] attribute displayed as yet another informational message (see
Figure 4).
That wraps up the example application. I hope at this point you can see that reflection services and custom attributes can be quite helpful in your real-world applications, and are not limited to tool builders.