This is a question about tidyness. The project is already working, I'm satisfied with the design but I have a couple of loose ends that I'd like to tie up.
My project has a plugin architecture. The main body of the program dispatches work to the plugins that each reside in their own AppDomain.
The plugins are described with an interface, which is used by the main program (to get the signature for invoking DispatchTaskToPlugin) and by the plugins themselves as an API contract:
namespace AppServer.Plugin.Common
{
public interface IAppServerPlugin
{
void Register();
void DispatchTaskToPlugin(Task t);
// Other methods omitted
}
}
In the main body of the program Register() is called so that the plugin can register its callback methods with the base class, and then later DispatchTaskToPlugin() is called to get the plugin running.
The plugins themselves are in two parts. There's a base class that implements the framework for the plugin (setup, housekeeping, teardown, etc..). This is where DispatchTaskToPlugin is actually defined:
namespace AppServer.Plugin
{
abstract public class BasePlugin : MarshalByRefObject,
AppServer.Plugin.Common.IAppServerPlugin
{
public void DispatchTaskToPlugin(Task t)
{
// ...
// Eventual call to actual plugin code
//
}
// Other methods omitted
}
}
The actual plugins themselves only need to implement a Register() method (to give the base class the delegates to call eventually) and then their business logic.
namespace AppServer.Plugin
{
public class Plugin : BasePlugin
{
override public void Register()
{
// Calls a method in the base class to register itself.
}
// Various callback methods, business logic, etc...
}
}
Now in the base class (BasePlugin) I've implemented all kinds of convenience methods, collected data, etc.. for the plugins to use. Everything's kosher except for that lingering method DispatchTaskToPlugin().
It's not supposed to be callable from the Plugin class implementations -- they have no use for it. It's only needed by the dispatcher in the main body of the program. How can I prevent the derived classes (Plugin) from seeing the method in the base class (BasePlugin/DispatchTaskToPlugin) but still have it visible from outside of the assembly?
I can split hairs and have DispatchTaskToPlugin() throw an exception if it's called from the derived classes, but that's closing the barn door a little late. I'd like to keep it out of Intellisense or possibly have the compiler take care of this for me.
Suggestions?