这是关于整洁的问题。该项目已经开始工作,我对设计感到满意,但我有一些松散的目标,我想要合作。
我的项目有一个插件架构。程序的主体派遣工作到插件,每个插件都驻留在他们自己的AppDomain中。
插件用接口描述,主程序使用该接口(获取调用DispatchTaskToPlugin
的签名),插件本身作为API合同使用:
namespace AppServer.Plugin.Common
{
public interface IAppServerPlugin
{
void Register();
void DispatchTaskToPlugin(Task t);
// Other methods omitted
}
}
在程序的主体Register()
中调用,以便插件可以使用基类注册其回调方法,然后调用DispatchTaskToPlugin()
以使插件运行。
插件本身分为两部分。有一个基类实现了插件的框架(设置,内务处理,拆卸等)。这是实际定义DispatchTaskToPlugin
的地方:
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
}
}
实际的插件本身只需要实现一个Register()
方法(给代表最终调用的基类),然后再实现它们的业务逻辑。
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...
}
}
现在在基类(BasePlugin
)中我已经实现了各种便利方法,收集的数据等..供插件使用。除了那种挥之不去的方法DispatchTaskToPlugin()
之外,一切都是洁净的。
不应该可以从Plugin
类实现中调用 - 它们没有用处。只有程序主体中的调度员才需要它。 如何防止派生类(Plugin
)看到基类(BasePlugin/DispatchTaskToPlugin
)中的方法,但仍然可以从程序集外部看到它?
我可以拆分头发并让DispatchTaskToPlugin()
抛出一个异常,如果它是从派生类调用的,但是那个谷仓门稍微关闭了。我想让它远离Intellisense,或者让编译器为我处理这个问题。
建议?
答案 0 :(得分:1)
如果插件只是真的要覆盖一个方法,我建议你让它们实现一个只有一个方法的接口。然后你当前的BasePlugin
可以使用组合而不是继承来处理“真实”基于界面的插件。可能需要将某些内容传递给Register
,以便插件可以订阅事件,但也可以表示为接口,以便插件只能看到您想要的内容。
答案 1 :(得分:1)
您可以使用显式实现在BasePlugin中私下实现DispatchTaskToPlugin
public class Task
{
}
public interface IAppServerPlugin
{
void Register();
void DispatchTaskToPlugin(Task t);
}
abstract public class BasePlugin : MarshalByRefObject, IAppServerPlugin
{
public abstract void Register();
void IAppServerPlugin.DispatchTaskToPlugin(Task t)
{
}
}
public class Plugin : BasePlugin
{
override public void Register()
{
}
public void Something()
{
this.DispatchTaskToPlugin(null); // Doesn't compile
base.DispatchTaskToPlugin(null); // Doesn't compile
}
}
class Program
{
static void Main(string[] args)
{
Plugin x;
x.DispatchTaskToPlugin(null); // Doesn't compile
}
}