I have a class to process an excel file, with multiple sheets. The class is called ExcelFileProcessor (inherits from IFileProcessor). My current implementation is within the ExcelFileProcessor class, I have different methods to process different sheets.
private void GenerateClientDataObj()
{
this.ReadLocationsFromFile();
this.ReadOpHoursFromFile();
this.ReadHolidaysFromFile();
this.ReadProductsServicesFromFile();
this.ReadUsersFromFile();
// set the error list
clientDataObj.ErrorList = importDataErrors;
}
I wanted to structure this code and decided to have a ISheetProcessor abstract class to process different sheets in the excel file. This class will have two methods:
// check if the given sheet exists in the excel file
ValidateSheet();
// process the given sheet and read the content in to an object in memory
ProcessSheet();
Since I have multiple sheets, I will have to create different instances of the ISheetProcessor within the ExcelFileProcessor or inject them. Can someone tell me the best way to do that?
I use the strategy pattern to decide which file processor to use. The code is given below:
In the controller:
var fileExtension = fileUtility.FileExtension;
// Pass the control to the appropriate file processor to read the file content
ProvisioningContext provisioningContext;
switch (fileExtension)
{
case ".xls":
case ".xlsx":
provisioningContext = new ProvisioningContext(new ExcelFileProcessor(), clientId, sheetsToProcess, fileUtility);
break;
case ".csv":
provisioningContext = null;
break;
default:
provisioningContext = null;
break;
}
return provisioningContext.ProcessFileContent();
ProvisioningContext class:
public ProvisioningContext(IFileProcessor fileProcessor, int clientId, IList<int> sheets, FileUtil fileUtil)
{
this.fileProcessor = fileProcessor;
}
public IList<ImportDataError> ProcessFileContent()
{
try
{
string[] filesArray = new string[fileUtil.FileCount];
filesArray[0] = fileUtil.GenerateFileName();
// proces the file content, validate and store in the database.
fileContent = fileProcessor.ReadContentFromFile(filesArray, sheetsToProcess);
SaveClientData();
// return the list of errors to the user
return fileContent.ErrorList;
}
catch (IOException ioException)
{
eventLogRepository.LogEvent(ioException, clientId, EventLogActionEnum.Provisioning_FileRead, EventLogSourceEnum.WebApplication);
throw;
}
catch(IndexOutOfRangeException indexOutOfRangeException)
{
eventLogRepository.LogEvent(indexOutOfRangeException, clientId, EventLogActionEnum.Provisioning_FileRead, EventLogSourceEnum.WebApplication);
throw;
}
catch (FormatException formatException)
{
eventLogRepository.LogEvent(formatException, clientId, EventLogActionEnum.Provisioning_FileRead, EventLogSourceEnum.WebApplication);
throw;
}
catch (Exception ex)
{
eventLogRepository.LogEvent(ex, clientId, EventLogActionEnum.Provisioning_FileRead, EventLogSourceEnum.WebApplication);
throw;
}
}
In the ExcelFileProcessor class:
public override ClientData ReadContentFromFile(string[] filePaths, IList<int> sheets = null)
{
// for Excel reader, there will only be one file.
this.OpenClientDataFile(filePaths[0]);
// perform initial validations on the file being read to ensure the necessay worksheets are available
string fileErrors = this.ValidateFile(sheets);
if (!string.IsNullOrEmpty(fileErrors))
{
throw new InvalidOperationException(fileErrors);
}
this.GenerateClientDataObj();
return clientDataObj;
}
Aucun commentaire:
Enregistrer un commentaire