For more ideas, read up on
Dependency Injection. In this paper Fowler gives several ways to configure options like this ... setters, constructors, etc.
You already have a good grip on
Dependency Inversion ... your core modules define the interfaces and customer plug ins implement them.
I borrowed an "Application Assembler" concept from Fowler's paper, though I'm not sure how close it is to his description any more. It reads configuration and "pushes" settings to objects that need them. It's very easy for
unit tests to set mock configurations, and avoids dependencies from the core module on the configuration module. The assembler has lots of:
[ December 06, 2005: Message edited by: Stan James ]