Building the Extensible Windows Forms Application
The final step is to create a new Windows Forms application (MyExtensibleApp
) that allows users to select a snap-in using a standard Windows Open dialog box. Set a reference to the CommonSnappableTypes.dll assembly, but not
the CSharpSnapIn.dll or Vb2005SnapIn.dll code libraries. Remember that the whole goal of this application is to make use of dynamic loading, late binding, and reflection to determine the "snappability" of external binaries created by third-party vendors.
I won't bother to discuss all the details of building the Windows Form discussed in this article. Basically though, place a MenuStrip component onto the Forms designer, and define a topmost menu item named Tools
that provides a single submenu named Snap In Module
. The Windows Form should also contain a descriptive Label for a ListBox (named lstLoadedSnapIns
) that the form uses to display the names of each snap-in loaded by the user. Figure 1
shows the final GUI design.
|Figure 1. Sample Windows Form: The figure shows the final design of the sample application used to select and list loaded snap-ins.|
Next, be sure to update your initial C# file with using
directives for the System.Reflection and CommonSnappableTypes namespaces:
The code that handles the Click
event of the "Tools> Snap In Module" menu item (which you can create by double-clicking the menu item from the menu editor) displays a File Open dialog box and extracts the path to the selected file.
private void snapInModuleToolStripMenuItem_Click(
object sender, EventArgs e)
// Allow user to select an assembly to load.
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
if (LoadExternalModule(dlg.FileName) == false)
"Nothing implements IAppFunctionality!");
The preceding code passes the user-selected assembly path to a helper function named LoadExternalModule()
for processing. LoadExternalModule()
inspects the selected assembly and returns false
when it is unable to find a type implementing IAppFunctionality; therefore, the Click
method handles that possibility by displaying a message to the end user.
method performs the following core tasks:
- Dynamically loads the assembly into memory via the Assembly.LoadFrom() method.
- Determines if the assembly contains a type implementing IAppFunctionality by analyzing the type information for each type in the assembly.
When LoadExternalModule finds a type that implements IAppFunctionality, it calls the DoIt()
method and adds the fully qualified name of the type to the ListBox.
private bool LoadExternalModule(string path)
bool foundSnapIn = false;
IAppFunctionality itfAppFx = null;
Assembly theSnapInAsm = null;
// Dynamically load the selected assembly.
theSnapInAsm = Assembly.LoadFrom(path);
// If any error at all takes place, just
// return false.
// Get all types in assembly.
Type theTypes = theSnapInAsm.GetTypes();
// See if the type implements IAppFunctionality.
for (int i = 0; i < theTypes.Length; i++)
Type t = theTypes[i].GetInterface(
if (t != null)
foundSnapIn = true;
// Use late binding to create the type.
object o = theSnapInAsm.CreateInstance(
// Call DoIt() off the extracted interface.
itfAppFx = o as IAppFunctionality;
Note that the for
loop shown above iterates over all types in the assembly to handle the possibility that a single assembly has multiple snap-ins.