NOTE: In order to run the demo, you must have the PDC 2001 release of Visual Studio. NET otherwise you won't have the correct system dlls. You can still download the source and build it.
Introduction
Table of Contents
Introduction
After writing my first article on loading types at runtime in mid-December I’ve since started a re-write of my type interface (after seeing a fatal flaw in my design). In doing so I also realized that the code to load my new types looked nearly identical to what I used before; in fact, the code for most people’s use would probably look the same.
So I broke it out into its own class, and created a fancy splash screen to go with it.
Compiling the source code
When you extract the source you will have a setup.bat in the root directory, run this to setup the strong name key files (snk). You may have to use Visual Studio's provided command line shortcut to ensure that your path is setup correctly. In order for the project to work you must sign your assemblies (though you probably don't have to sign the main executable I do because it doesn't take much work to do, and gives added peace of mind to your users).
Once you compile all three projects place the resulting DLLs in the directory with the main executable, you should only need to copy the dll from the StandardTypes project. You can now run the program, and you should see the splash screen come up, load a type, then disappear.
TypeLoader
The type loader will be doing the grunt work for you, all you have to do is tie into it via the TypeLoading
event, and optionally the TypeLoaded
event.
Types property
public TypeCollection Types { get; set; }
This is the collection of types that have been loaded via the TypeLoading
event. It is a strongly typed Collection of Type objects (generated via Microsoft's Collection Generator).
TypeLoading event
public event TypeLoadingEventHandler TypeLoading;
public delegate void TypeLoadingEventHandler(object sender, <BR> TypeLoadingEventArgs e);
This event will be fired for every type that the class encounters while it is loading. The TypeLoading
property contains the Type object in question. Set the Cancel
property to true to not load the type, set it to false to load the type.
TypeLoaded event
public event TypeLoadedEventHandler TypeLoaded;
public delegate void TypeLoadedEventHandler(object sender, <BR> TypeLoadedEventArgs e);
This event will be fired for every type that was successfully loaded by the system. That is, it'll be fired for every type where the TypeLoading
event's Cancel property was false when it returned. The TypeLoaded
property contains the Type object that was loaded. This event is provided only as a service and is not required to be listened to.
LoadTypesFromDirectory method
public void LoadTypesFromDirectory(string path);
public void LoadTypesFromDirectory(string path, string searchPattern);
public void LoadTypesFromDirectory(string path, <BR> string searchPattern, bool recurseSubdirectories);
If not specified searchPattern
will default to "*.dll" and recurseSubdirectories
will be false.
This method is the whole purpose of the class to begin with. It will search a directory for types, and notify the caller when it finds some via the TypeLoading
event.
The path should be suitable for the System.IO.Directory
class, and the searchPattern
should work with the System.IO.Directory.GetFiles
method.
Each of the overloads in the end calls down to a protected method, LoadTypesFromDirectoryRecursive
.
None of these methods clears the collection of types.
Clear method
void Clear();
This method removes all Types from the TypeCollection
.
TypeImplementsInterface static method
public static bool TypeImplementsInterface(Type type, Type interfaceType);
Returns true if the given type implements the interface name passed. This currently goes through the list of all types implemented and compares the full name of both types. Since its possible for two different assemblies to have the same namespace, its recommended that you prefix all namespaces with your company name.
The Splash Screen
The splash screen has 2 customizable parts to it
The bitmap is a 352x72 pixel image displayed on the top portion of the window.
The Type Listing displays all the types that have been successfully loaded by the program. In this case the listing shows a bitmap and a name gotten from the type.
How to use it
public void ShowSplashScreen()
{
SplashScreen splash = new SplashScreen();
TypeCollection typesLoaded = splash.DoSplash();
}
Simple eh? Not quite that simple though, you have to modify the source to the splash screen, just a bit so that it looks for the types you want to use in your program. The method you need to change is loader_TypeLoading
. It currently shows an example of how to look for an interface being implemented by a class.
How it works
All the work is done in the events for the TypeLoader object.
In the TypeLoading
event it does a compare on the type to see if it implements the IType
interface from the Types namespace. The compare is done using TypeLoader'
s only static method, TypeImplementsInterface
.
In the TypeLoaded
event it gets the picture from the IType
, adds it to the imagelist; then adds it to the ListView
. Pretty simple, and gives the effect I was looking for.
Summary
If you look through the code you'll see that my root namespace is Takklesoft.CollectorsDatabase
. No I didn't forget to change it, this is code I've ripped from my current project. So if I ever get it released you'll know how I did the splash screen.
As always any questions or comments, leave them below or e-mail me.
The code I provide here is free for anyone to use, I don't require anything in return, but a mention in some documents or an about box would be nice :-)