這個問題可能有點奇怪。方案如下:阻止訪問繼承成員
- 有一個稱爲對插件的接口
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'。這些公共成員不應該被派生插件類訪問,因爲它們只能被主程序集用於插件通信。 –