65.9K
CodeProject is changing. Read more.
Home

TypeLoader for .NET

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.65/5 (6 votes)

Jan 4, 2002

5 min read

viewsIcon

78697

downloadIcon

1520

Class and splash screen to load custom types at runtime.

Sample Image - typeloader.gif

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, 
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, 
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, 
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

  • Bitmap
  • Type Listing

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();
	// Use the typeCollection in your main program
}

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 :-)