我面临一个独特的问题。我们的应用程序中有一个下载功能,我们有一个下拉列表,其中包含用户需要下载的文件类型,即pdf,csv或excel
为了实现这个问题,我们创建了一个接口IFileDownaload和三个不同的类clsCSV,ClsPDF和clsExcel,它们由IFileDownaload实现
现在我的问题是如何根据Dropdown值启动一个类,因为我不想写下if-else语句
if(option ==" pdf")type
因为将来如果我们引入新的文件下载类型,那么它将影响我们重新编写整个逻辑
任何建议
答案 0 :(得分:1)
您可以为您拥有的每个班级定义缩写,以便您拥有以下内容:
public interface IFileDownload
{
string Abbreviation { get; }
}
public class PDFDonwload : IFileDownload
{
public string Abbreviation { get; private set; }
}
然后你可以制作一些类,即工厂,它拥有你拥有的所有文件下载程序的实例,并通过它们的缩写迭代,直到找到合适的类。它可以像这样实现:
public static class DownloadHander
{
private static List<IFileDownload> _handlers;
static DownloadHander()
{
_handlers = new List<IFileDownload>();
}
public static void Initialize()
{
_handlers.Add(new PDFDonwload());
}
public static Stream HandleDownload(string abbreviation)
{
foreach (var fileDownload in _handlers)
{
if (fileDownload.Abbreviation == abbreviation)
{
//and here you make a stream for client
}
}
throw new Exception("No Handler");
}
}
答案 1 :(得分:1)
当我有许多实现某种类型的类而这些类是无状态services而不是entities时,我使用的是Registry而不是Factory。
您的注册表中包含所有IFileDownload
实例类的实例:
public class FileDownloaderRegistry
{
private readonly IFileDownload[] _downloaders;
public FileDownloaderRegistry(IFileDownload[] downloaders)
{
_downloaders = downloaders;
}
}
然后,您在IFileDownload
上有一个属性,表示下载程序处理的文件类型:
public interface IFileDownload
{
string FileType { get; }
// etc.
}
最后,您的注册表中的方法采用文件类型并将工作委托给相应的下载程序:
public string DownloadFile(string fileName, string fileType)
{
var handlingDownloader = _downloaders
.FirstOrDefault(d => d.FileType == fileType);
if (handlingDownloader == null)
{
// Probably throw an Exception
}
return handlingDownloader.Download(fileName);
}
DI容器通常会隐式理解数组,因此只需注册各种IFileDownload
s就应该在注入到Registry的构造函数中的数组中使用它们。使用StructureMap的例如:
For<IFileDownload>().Use<ClsCSV>();
For<IFileDownload>().Use<ClsPDF>();
For<IFileDownload>().Use<ClsExcel>();
添加新的IFileDownload
是一个问题,用你的DI容器编写课程和adding it to the set of IFileDownload
s registered。您还可以让容器管理每个对象的生命周期(如果它们是无状态的),它们只在每个对象首次需要时进行实例化。