Ho un FtpServerDataSeriesProvider
che viene utilizzato per fornire serie di dati da file server Ftp:
public interface class FtpServerDataSeriesProvider
{
IEnumerable<DataSeries> GetDataSeries();
}
Ha diverse implementazioni concrete specifiche per la società proprietaria del server Ftp, come:
public class Company1FtpServerDataSeriesProvider : FtpServerDataSeriesProvider
{
public IEnumerable<DataSeries> GetDataSeries()
{
// code to extract data series from ftp server files
}
}
public class Company2FtpServerDataSeriesProvider : FtpServerDataSeriesProvider
{
public IEnumerable<DataSeries> GetDataSeries()
{
// code to extract data series from ftp server files
}
}
Il processo di estrazione della serie di dati è gestito da un FileDataMiner
che viene utilizzato per estrarre i dati dal contenuto di tipi di file specifici:
public interface IFileDataSeriesMiner
{
IEnumerable<DataSeries> GetDataSeries(byte [] fileContent);
}
Il parametro del metodo GetDataSeries()
è un array di byte non elaborati che presenta il contenuto del file, all'interno di questo metodo sarebbe codificato / trasformato in MemoryStream
a seconda del tipo di file targer.
// To get data from CSV-based file
public abstract CsvFileDataSeriesMiner : IFileDataMiner
{
public abstract IEnumerable<DataSeries> GetDataSeries(byte [] fileContent);
// here might be some protected csv-related helper methods
}
// To get data from Xls-based file
public abstract XlsFileDataSeriesMiner : IFileDataMiner
{
public abstract IEnumerable<DataSeries> GetDataSeries(byte [] fileContent);
// here might be some protected xls-related helper methods
}
Poi ci sono anche alcune classi concrete che rappresentano diversi formati di dati di file di input (ciascuna azienda memorizza i dati in un formato diverso):
public class Company1CsvFileDataSeriesMiner : CsvFileDataSeriesMiner
{
public IEnumerable<DataSeries> GetDataSeries(byte [] fileContent)
{
// do actual stuff
}
}
public class Company2CsvFileDataSeriesMiner : CsvFileDataSeriesMiner
{
public IEnumerable<DataSeries> GetDataSeries(byte [] fileContent)
{
// do actual stuff
}
}
public class Company1XlsFileDataSeriesMiner : XlsFileDataSeriesMiner
{
public IEnumerable<DataSeries> GetDataSeries(byte [] fileContent)
{
// do actual stuff
}
}
public class Company2XlsFileDataSeriesMiner : XlsFileDataSeriesMiner
{
public IEnumerable<DataSeries> GetDataSeries(byte [] fileContent)
{
// do actual stuff
}
}
Ora, per poter FtpServerDataSeriesProvider
in grado di estrarre dati da specifici contenuti in formato file, ho bisogno di passare / iniettare IFileDataSeriesMiner
in qualche modo al FtpServerDataSeriesProvider
costruttori di calcestruzzo.
Ma, potrebbe essere che il FTPServer ci sono Csv e XLS (e altri) file presenti, quindi ho bisogno di essere in grado di selezionare la corretta IFileDataSeriesMiner dinamicamente all'interno% co_de codice% a seconda del formato del file attualmente in fase di elaborazione.
Quindi, le mie domande sono:
- Devo iniettare una fabbrica di
FtpServerDataSeriesProvider
inIFileDataSeriesMiner
/Company1FtpServerDataSeriesProvider
costruttori e quindi decidere quale oggetto minatore ho bisogno basandoci ad es. estensione del file?
Il factory del minatore per Company1 sarebbe simile a questo:
public interface IFileDataSeriesMinerFactory
{
IFileDataSeriesMiner CreateMiner(string fileName);
}
public class Company1FileDataSeriesMinerFactory : IFileDataSeriesMinerFactory
{
// basing on file extension suitable Miner object is created
public static IFileDataSeriesMiner CreateMiner(string fileName);
}
public class Company1FtpServerDataSeriesProvider : FtpServerDataSeriesProvider
{
private IFileDataSeriesMinerFactory minerFactory;
public Company1FtpServerDataSeriesProvider(IFileDataSeriesMinerFactory minerFactory)
{
this.minerFactory = minerFactory;
}
// code ommited
}
- Quando ci sono diversi file che devono essere elaborati all'interno del server, dovrei chiamare la fabbrica del minatore per ogni file che necessita di elaborazione, quindi per ogni file verrà creato un nuovo oggetto Miner - ok?
Codice semplificato per Company1FtpServerDataSeriesProvider:
public class Company1FtpServerDataSeriesProvider : FtpServerDataSeriesProvider
{
private IFileDataSeriesMinerFactory minerFactory;
public Company1FtpServerDataSeriesProvider(IFileDataSeriesMinerFactory minerFactory)
{
this.minerFactory = minerFactory;
}
public IEnumerable<DataSeries> GetDataSeries()
{
var ftpServerFilesToRead = ftpClient.GetFiles();
foreach (string filepath in ftpServerFilesToRead)
{
byte[] fileBytes = ftpRequest.DownloadData(filepath); // Read file bytes
var miner = minerFactory.CreateMiner(filename); // Create miner for current file to extract data series
foreach (var dataSeries in miner.GetDataSeries(fileBytes))
{
yield return dataSeries;
}
}
}
}