pm1*_*100 3 .net c# plugins static-classes
我知道如何在c#中制作可插拔的东西.定义一个接口,Activator.CreateInstance(<class>)等等.或者我可以有一个显式创建插件类实例的代码路径.很多种方法.
但是,如果我想要插件的服务是静态的(我知道我可以重构,所以它不是,但这不是问题的重点)
具体例子.我有一个提供磁盘I/O抽象的类(读取文件,列表目录,....).现在我想要这种抽象的不同实现,它可以提供来自真实FS,数据库的文件.
根据Olivier Jacot-Descombes的回复,我会有一个FileSystem类(这是真的)这样的
public static class FileSystem
{
static IFSImplemenation s_imple;
static FileSystem()
{
if(<some system setting>)
// converted to singleton instead of static
s_imple = new OldFileSystem()
else
s_imple = new DbFileSystem();
}
public static byte[] ReadFile(string path)
{
return s_imple.ReadFile(path);
}
...
}
Run Code Online (Sandbox Code Playgroud)
重申 - 我有一大堆代码,我不想改变,所以保持调用签名相同很重要 - 这个解决方案实现了
你不能,这是.NET中类型系统和大多数面向对象系统/语言的限制.
原因是"可插入的东西"(正如你所指的那样)需要多态才能有效.
您定义一个合同(一个接口,在.NET中说),然后您实现该合同.您的系统只处理合同.
静态成员在.NET中不是多态的,因此您永远无法让它们实现合同.
对于您的磁盘I/O抽象示例,您不会为此创建静态类,您将创建一个接口,并实现接口,传递接口.
当然,使用界面的好处是可以更轻松地测试合同执行的双方:
在磁盘I/O抽象的情况下,对于调用合同的所有内容,您永远不必担心实际触摸文件系统,您只需要使合同行为(通过适当的模拟设置)就像触摸它一样文件系统.
如果您有通过静态成员公开的现有服务,并且您希望能够将其与另一个实现交换,那么您将必须执行以下操作: