这个问题可能有点奇怪。方案如下:阻止访问继承成员
- 有一个称为对插件的接口
IPlugin
- 没有为插件称为
PluginBase
- 一个抽象基类(它实现接口)这些被存储类库 内部
现在每个人都应该能够通过创建一个新的类库和一个派生自PluginBase
的插件类来创建自己的插件。
PluginBase
类将提供很多公共属性,这些属性用于从基本工具与插件接口进行通信。这是通过反思完成的;该工具将搜索基于接口IPlugin
的类并创建该类的一个实例。
现在的问题是,这些公共属性是必要的插件机制,但不应该从派生的插件类访问或更改。简而言之:用户定义的插件类不应该能够访问其基类PluginBase
的多个公共成员。
这可能不知?我知道我通常应该使用private
作为这些属性(所以派生类无法访问它们),但由于基类也充当插件接口,所以这是不可能的。
解决方案(基于Fabjan和Luaan的答案):
// basic plugin interface (IPlugin.dll)
public interface IPlugin
{
// plugin communication interface
string SomeProperty { get; set; }
void SomeMethod();
// public interface
string Name { get; }
void Run();
}
// plugin base class (IPlugin.dll)
public class PluginBase : IPlugin
{
string IPlugin.SomeProperty
{
get { return "Something"; }
set { /* ... */ }
}
void IPlugin.SomeMethod()
{
Console.WriteLine("Something");
}
public string Name
{
get { return "MyName"; }
}
public void Run()
{
// ...
}
}
// user-defined plugin (MyPlugin.dll)
public class MyPlugin : PluginBase
{
public MyPlugin()
{
// will not work
this.SomeProperty ...
}
}
// main assembly
static void Main(string[] args)
{
Assembly asm = Assembly.LoadFrom(@"path\to\assembly");
var type = asm.GetTypes().FirstOrDefault(t => t.GetInterface("NamespaceOfIPlugin.IPlugin", true) != null);
NamespaceOfIPlugin.IPlugin plugin = (NamespaceOfIPlugin.IPlugin)Activator.CreateInstance(type);
// works as expected
plugin.SomeMethod();
}
这听起来对我来说,该信息不应该在该类。如果一个类拥有公共属性,那么它就不允许访问,那么它觉得这必须是关于该类的元数据,可能可能存储在别处?你能否举一个应该在班上但不在该班控制下的财产的例子?这可能有助于使问题和要求更易于理解。 – Chris
这些公共属性是从接口来的吗? – gsharp
@gsharp是的公共属性来自“IPlugin”接口。正如我所说的,主程序集将加载插件程序集(DLL),该程序集包含一个用户创建的插件类,它从'PluginBase'派生,因此实现'IPlugin'。主程序搜索这个类,创建一个实例,然后访问一些公共属性。主要组件只知道'IPlugin'。这些公共成员不应该被派生插件类访问,因为它们只能被主程序集用于插件通信。 –