C# 按id列出的接口实例
我们有不同类型的图像,我们将图像存储在磁盘上相应的子文件夹中,并将元数据存储在数据库中,包括fileTypeId。 目前我们有:C# 按id列出的接口实例,c#,enums,interface,solid-principles,open-closed-principle,C#,Enums,Interface,Solid Principles,Open Closed Principle,我们有不同类型的图像,我们将图像存储在磁盘上相应的子文件夹中,并将元数据存储在数据库中,包括fileTypeId。 目前我们有: public enum FileTypes { Document=1, ProfileProto ... } 及 像这样的 这违反了SOLID的打开/关闭原则 因此,我尝试创建以下内容: public class DocumentFileType : IFileType { public int Id => 1; pub
public enum FileTypes
{
Document=1,
ProfileProto
...
}
及
像这样的
这违反了SOLID的打开/关闭原则
因此,我尝试创建以下内容:
public class DocumentFileType : IFileType
{
public int Id => 1;
public string Subfolder => "documents";
}
但问题是,当我们将图像的元数据存储到数据库中时,我们将类型的id存储到数据库字段中。在这种情况下为1或2。
所以当我回来的时候,我应该做些
IFileType fileType=IFileType.instnceWithId(1)
但这当然是不可能的
我能做些什么来代替它呢?我会坚持使用带有枚举的简单解决方案,并使用一个属性用子目录字符串来修饰它,以便将所有需要的数据放在一个地方:
public enum FileTypes
{
[SubDirectory("documents")]
Document = 1,
[SubDirectory("profilefotos")]
ProfileFoto = 2
}
为了使代码更具可扩展性,我认为您需要某种注册表来存储所有已知的文件类型。注册表可以是库的一部分并公开,以便外部代码可以注册它们自己的文件类型
public class DocumentFileTypeRegistry
{
IDictionary<int, IFileType> _registeredFileTypes = new Dictionary<int, IFileType>();
public void RegisterType(IFileType type)
{
_registeredFileTypes[type.Id] = type;
}
public IFileType GetTypeById(int id)
{
return _registeredFileTypes[id];
}
}
public class DocumentFileType : IFileType
{
public int Id => 1;
public string Subfolder => "documents";
}
public class PhotoFileType : IFileType
{
public int Id => 2;
public string Subfolder => "photos";
}
我不认为存储
文件类型
和1
有什么区别,因为它们最终是,同样,你可以使用工厂模式……但是对于一种文件类型来说,这是不是太过分了……是否还会有另一组编码器需要使用你的代码并在没有访问权限的情况下对其进行扩展?我认为你发现C#的enum
不是非常开放/封闭的。但是你的选择看起来更糟。如果你在一个地方切换枚举,那么这是一个可以忍受的“违规”。否则,你引入复杂性是为了一点好处。也许你正在寻找这个,嗯,这很好,我喜欢。但是我仍然需要修改它(midify它),所以它仍然违反了打开/关闭,不是吗?而且它看起来是cimplex来检索值是的,您需要反射来访问子目录值(看起来有点难看,但实际上没有那么复杂)。要使用新的文件类型扩展它,您仍然需要更改枚举。有了这个方法,您只能删除switch语句。我添加了另一个答案,但也记住了雅格尼原则;-)有了这个,您需要注册它,所以您需要再次修改它
public class DocumentFileTypeRegistry
{
IDictionary<int, IFileType> _registeredFileTypes = new Dictionary<int, IFileType>();
public void RegisterType(IFileType type)
{
_registeredFileTypes[type.Id] = type;
}
public IFileType GetTypeById(int id)
{
return _registeredFileTypes[id];
}
}
public class DocumentFileType : IFileType
{
public int Id => 1;
public string Subfolder => "documents";
}
public class PhotoFileType : IFileType
{
public int Id => 2;
public string Subfolder => "photos";
}
_fileTypeRegistry = new DocumentFileTypeRegistry();
_fileTypeRegistry.RegisterType(new DocumentFileType());
_fileTypeRegistry.RegisterType(new PhotoFileType());
//retrieve the type by id
var fileType = _fileTypeRegistry.GetTypeById(1);