从派生类隐藏基类方法,但在程序集外部仍然可见

时间:2009-07-10 14:43:21

标签: c# class plugins appdomain

这是关于整洁的问题。该项目已经开始工作,我对设计感到满意,但我有一些松散的目标,我想要合作。

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

建议?

2 个答案:

答案 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
    }
}