Dynamically Load Components From Packages at Run Time (cont'd)
Load Dynamic Run-Time Packages
With the LoadPackage function, you can dynamically load run-time packages. According to the online help, LoadPackage loads the specified package, checks for duplicate modules, and calls the initialization sections of each unit the package contains. You have to store the HModule that LoadPackage returns because you'll need the HModule value to unload the package with UnloadPackage. The UnloadPackage function calls the finalize sections from each unit and then unloads the package:
// application unit
var
Plugin: HModule;
initialization
Plugin := LoadPackage('Plugin42.bpl');
finalization
if Plugin <> 0 then
UnloadPackage(Plugin)
end.
So we can load a run-time package on demand. Big deal. Will we be able to use all components defined in the run-time package automatically? Well, as a matter of fact, no, we won't. Loading a package has no immediate benefit because the components inside the package need to be made available for use. And this is the tricky part; we can't do that in our executable without a little help from the run-time package itself. Our components need to be registered, using the RegisterClasses function (defined in the Classes unit), as follows:
// package unit
initialization
RegisterClasses([T42Edit]);
finalization
UnRegisterClasses([T42Edit]);
end.
Since LoadPackage automatically calls the initialization section and UnloadPackage calls the finalization section, it'll register (and unregister) the component T42Edit automatically as well.
Check for Run-Time Components
In order to verify that everything went OK and the T42Edit is indeed "available," call the FindClass function. This function takes a string argument (the name of the class, T42Edit in our case) and returns an object reference like TPersistentClass. If the class with the specified name cannot be found (i.e., is not registered within the module), then FindClass raises an exception and returns nil (see the code listing in the following section for the example usage). As a consequence, you should use FindClass in a try-except block, but you probably shouldn't allow this exception to be shown to the end-user.
How do I dynamically load packages and use their components at run-time?
Write Delphi packages, dynamically load them, and create dynamic component instances in a way that can be the basis for a dynamic application plug-in architecture.
Find Out More
The T42Edit and T42Label components are implemented on Bob Swart's Web site in the Tip-of-the-Hat section.
What are your experiences with component use at Run-Time? Do you have a better way to build dynamic application plug-in architectures. Let us know in the database development discussion groups!