0

这是一个关于整洁的问题。该项目已经开始运作,我对设计感到满意,但我有一些松散的地方想要解决。

我的项目有一个插件架构。程序的主体将工作分派给每个驻留在自己的 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,或者可能让编译器为我处理这个问题。

建议?

4

2 回答 2

1

如果插件真的只是为了覆盖一种方法,我建议你让它们实现一个只包含一种方法的接口。然后你的当前BasePlugin可以使用组合而不是继承来处理仅基于接口的“真实”插件。它可能需要传递一些东西Register,以便插件可以订阅事件,但这也可以表示为一个接口,以便插件只看到你想要的东西。

于 2009-07-10T14:48:13.687 回答
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
    }
}
于 2009-07-10T14:54:01.260 回答