forked from ddrilling/AsbCloudServer
Рефакторинг парсинга
1. Добавлен шаблон для сообщений 2. Поправлен naming у сервисов парсинга траекторий 3. Удалена регистрация зависимостей парсеров траекторий 4. Внутри фабрики добавлено создание отдельного scope. Фикс нейминга констант
This commit is contained in:
parent
c33b7d086a
commit
1b3c06c927
@ -1,6 +1,4 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Requests.ParserOptions;
|
using AsbCloudApp.Requests.ParserOptions;
|
||||||
|
|
||||||
@ -35,4 +33,5 @@ public interface IParserService<TDto, in TOptions> : IParserService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IParserService
|
public interface IParserService
|
||||||
{
|
{
|
||||||
|
const string MessageTemplate = "Лист: {0}, Строка: {1}, Столбец: {2}. {3}";
|
||||||
}
|
}
|
@ -45,7 +45,6 @@ using AsbCloudDb.Model.WellSections;
|
|||||||
using AsbCloudInfrastructure.Services.ProcessMaps;
|
using AsbCloudInfrastructure.Services.ProcessMaps;
|
||||||
using AsbCloudApp.Data.ProcessMapPlan;
|
using AsbCloudApp.Data.ProcessMapPlan;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudInfrastructure.Services.Trajectory.Parser;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure
|
namespace AsbCloudInfrastructure
|
||||||
{
|
{
|
||||||
@ -205,8 +204,6 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<TrajectoryPlanExportService>();
|
services.AddTransient<TrajectoryPlanExportService>();
|
||||||
services.AddTransient<TrajectoryFactManualExportService>();
|
services.AddTransient<TrajectoryFactManualExportService>();
|
||||||
services.AddTransient<TrajectoryFactNnbExportService>();
|
services.AddTransient<TrajectoryFactNnbExportService>();
|
||||||
services.AddTransient<TrajectoryPlanParserService>();
|
|
||||||
services.AddTransient<TrajectoryFactManualParserService>();
|
|
||||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||||
|
@ -21,21 +21,68 @@ public abstract class ParserServiceBase<TDto, TOptions> : IParserService<TDto, T
|
|||||||
this.serviceProvider = serviceProvider;
|
this.serviceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual ICollection<ValidationResult> ValidationResults { get; } = new List<ValidationResult>();
|
||||||
|
|
||||||
|
protected abstract string SheetName { get; }
|
||||||
|
|
||||||
public abstract ParserResultDto<TDto> Parse(Stream file, TOptions options);
|
public abstract ParserResultDto<TDto> Parse(Stream file, TOptions options);
|
||||||
|
|
||||||
public abstract Stream GetTemplateFile();
|
public abstract Stream GetTemplateFile();
|
||||||
|
|
||||||
|
protected virtual ValidationResultDto<TDto> ValidateRow(int rowNumber,
|
||||||
|
IDictionary<string, int> columnNumbers,
|
||||||
|
TDto dto)
|
||||||
|
{
|
||||||
|
var validationContext = new ValidationContext(dto, serviceProvider: null, items: null);
|
||||||
|
|
||||||
|
if (Validator.TryValidateObject(dto, validationContext, ValidationResults, true))
|
||||||
|
{
|
||||||
|
var validRow = new ValidationResultDto<TDto>
|
||||||
|
{
|
||||||
|
Item = dto
|
||||||
|
};
|
||||||
|
|
||||||
|
return validRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
var invalidRow = new ValidationResultDto<TDto>
|
||||||
|
{
|
||||||
|
Item = dto,
|
||||||
|
};
|
||||||
|
|
||||||
|
var warnings = new List<ValidationResult>();
|
||||||
|
|
||||||
|
foreach (var validationResult in from v in ValidationResults
|
||||||
|
let memberNames = v.MemberNames.Where(columnNumbers.ContainsKey)
|
||||||
|
select memberNames.Select(x =>
|
||||||
|
{
|
||||||
|
var columnNumber = columnNumbers[x];
|
||||||
|
var errorMessage = v.ErrorMessage;
|
||||||
|
var warningMessage = string.Format(IParserService.MessageTemplate, SheetName, rowNumber, columnNumber, errorMessage);
|
||||||
|
var warning = new ValidationResult(warningMessage, new[] { x });
|
||||||
|
return warning;
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
warnings.AddRange(validationResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidRow.Warnings = warnings;
|
||||||
|
|
||||||
|
return invalidRow;
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual ParserResultDto<TDto> ParseExcelSheet(IXLWorksheet sheet,
|
protected virtual ParserResultDto<TDto> ParseExcelSheet(IXLWorksheet sheet,
|
||||||
Func<IXLRow, ValidationResultDto<TDto>> parseRow,
|
Func<IXLRow, ValidationResultDto<TDto>> parseRow,
|
||||||
int columnCount,
|
int columnCount,
|
||||||
int headerRowsCount = 0)
|
int headerRowsCount = 0)
|
||||||
{
|
{
|
||||||
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < columnCount)
|
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < columnCount)
|
||||||
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
|
throw new FileFormatException($"Лист {SheetName} содержит меньшее количество столбцов.");
|
||||||
|
|
||||||
var count = sheet.RowsUsed().Count() - headerRowsCount;
|
var count = sheet.RowsUsed().Count() - headerRowsCount;
|
||||||
|
|
||||||
if (count > 1024)
|
if (count > 1024)
|
||||||
throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество строк.");
|
throw new FileFormatException($"Лист {SheetName} содержит слишком большое количество строк.");
|
||||||
|
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
return new ParserResultDto<TDto>();
|
return new ParserResultDto<TDto>();
|
||||||
|
@ -3,23 +3,30 @@ using System.Collections.Generic;
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Requests.ParserOptions;
|
using AsbCloudApp.Requests.ParserOptions;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
|
||||||
using AsbCloudInfrastructure.Services.Trajectory.Parser;
|
using AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services;
|
namespace AsbCloudInfrastructure.Services;
|
||||||
|
|
||||||
public class ParserServiceFactory
|
public class ParserServiceFactory : IDisposable
|
||||||
{
|
{
|
||||||
public const int IdTrajectoryFactManualParserService = 1;
|
public const int IdTrajectoryFactManualParser = 1;
|
||||||
public const int IdTrajectoryPlanParserService = 2;
|
public const int IdTrajectoryPlanParser = 2;
|
||||||
|
public const int IdProcessMapPlanDrillingParser = 3;
|
||||||
|
|
||||||
private readonly IDictionary<int, Func<IParserService>> parsers;
|
private readonly IDictionary<int, Func<IParserService>> parsers;
|
||||||
|
private readonly IServiceScope serviceScope;
|
||||||
|
|
||||||
public ParserServiceFactory(IServiceProvider serviceProvider)
|
public ParserServiceFactory(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
|
serviceScope = serviceProvider.CreateScope();
|
||||||
|
|
||||||
parsers = new Dictionary<int, Func<IParserService>>
|
parsers = new Dictionary<int, Func<IParserService>>
|
||||||
{
|
{
|
||||||
{ IdTrajectoryPlanParserService, () => new TrajectoryPlanParserService(serviceProvider) },
|
{ IdTrajectoryPlanParser, () => new TrajectoryPlanParser(serviceScope.ServiceProvider) },
|
||||||
{ IdTrajectoryFactManualParserService, () => new TrajectoryFactManualParserService(serviceProvider) }
|
{ IdTrajectoryFactManualParser, () => new TrajectoryFactManualParser(serviceScope.ServiceProvider) },
|
||||||
|
{ IdProcessMapPlanDrillingParser, () => new ProcessMapPlanDrillingParser(serviceScope.ServiceProvider) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,4 +40,9 @@ public class ParserServiceFactory
|
|||||||
return parserService.Invoke() as IParserService<TDto, TOptions>
|
return parserService.Invoke() as IParserService<TDto, TOptions>
|
||||||
?? throw new ArgumentNullException(nameof(idParserService), "Ошибка приведения типа");
|
?? throw new ArgumentNullException(nameof(idParserService), "Ошибка приведения типа");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
serviceScope.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,12 +5,12 @@ using ClosedXML.Excel;
|
|||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||||
|
|
||||||
public class TrajectoryFactManualParserService : TrajectoryParserService<TrajectoryGeoFactDto>
|
public class TrajectoryFactManualParser : TrajectoryParser<TrajectoryGeoFactDto>
|
||||||
{
|
{
|
||||||
protected override string SheetName => "Фактическая траектория";
|
protected override string SheetName => "Фактическая траектория";
|
||||||
protected override string TemplateFileName => "TrajectoryFactManualTemplate.xlsx";
|
protected override string TemplateFileName => "TrajectoryFactManualTemplate.xlsx";
|
||||||
|
|
||||||
public TrajectoryFactManualParserService(IServiceProvider serviceProvider)
|
public TrajectoryFactManualParser(IServiceProvider serviceProvider)
|
||||||
: base(serviceProvider)
|
: base(serviceProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
@ -2,26 +2,23 @@
|
|||||||
using AsbCloudApp.Data.Trajectory;
|
using AsbCloudApp.Data.Trajectory;
|
||||||
using ClosedXML.Excel;
|
using ClosedXML.Excel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Requests.ParserOptions;
|
using AsbCloudApp.Requests.ParserOptions;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||||
|
|
||||||
public abstract class TrajectoryParserService<T> : ParserServiceBase<T, IParserOptionsRequest>
|
public abstract class TrajectoryParser<T> : ParserServiceBase<T, IParserOptionsRequest>
|
||||||
where T : TrajectoryGeoDto
|
where T : TrajectoryGeoDto
|
||||||
{
|
{
|
||||||
private const int HeaderRowsCount = 2;
|
private const int HeaderRowsCount = 2;
|
||||||
private const int ColumnCount = 6;
|
private const int ColumnCount = 6;
|
||||||
|
|
||||||
protected TrajectoryParserService(IServiceProvider serviceProvider)
|
protected TrajectoryParser(IServiceProvider serviceProvider)
|
||||||
: base(serviceProvider)
|
: base(serviceProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract string SheetName { get; }
|
|
||||||
|
|
||||||
protected abstract string TemplateFileName { get; }
|
protected abstract string TemplateFileName { get; }
|
||||||
|
|
||||||
protected abstract ValidationResultDto<T> ParseRow(IXLRow row);
|
protected abstract ValidationResultDto<T> ParseRow(IXLRow row);
|
@ -5,12 +5,12 @@ using ClosedXML.Excel;
|
|||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||||
|
|
||||||
public class TrajectoryPlanParserService : TrajectoryParserService<TrajectoryGeoPlanDto>
|
public class TrajectoryPlanParser : TrajectoryParser<TrajectoryGeoPlanDto>
|
||||||
{
|
{
|
||||||
protected override string SheetName => "Плановая траектория";
|
protected override string SheetName => "Плановая траектория";
|
||||||
protected override string TemplateFileName => "TrajectoryPlanTemplate.xlsx";
|
protected override string TemplateFileName => "TrajectoryPlanTemplate.xlsx";
|
||||||
|
|
||||||
public TrajectoryPlanParserService(IServiceProvider serviceProvider)
|
public TrajectoryPlanParser(IServiceProvider serviceProvider)
|
||||||
: base(serviceProvider)
|
: base(serviceProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure;
|
namespace AsbCloudInfrastructure;
|
||||||
|
|
||||||
@ -39,8 +40,9 @@ public static class XLExtentions
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
throw new FileFormatException(
|
var message = string.Format(IParserService.MessageTemplate, cell.Worksheet.Name, cell.Address.RowNumber,
|
||||||
$"Лист '{cell.Worksheet.Name}'. {cell.Address.RowNumber} строка содержит некорректное значение в {cell.Address.ColumnNumber} столбце");
|
cell.Address.ColumnNumber, "Содержит некорректное значение");
|
||||||
|
throw new FileFormatException(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,7 +37,7 @@ public class TrajectoryParserTest
|
|||||||
Assert.Fail("Файла для импорта не существует");
|
Assert.Fail("Файла для импорта не существует");
|
||||||
|
|
||||||
var parserService = parserServiceFactory.Create<TrajectoryGeoPlanDto, IParserOptionsRequest>(
|
var parserService = parserServiceFactory.Create<TrajectoryGeoPlanDto, IParserOptionsRequest>(
|
||||||
ParserServiceFactory.IdTrajectoryPlanParserService);
|
ParserServiceFactory.IdTrajectoryPlanParser);
|
||||||
|
|
||||||
var trajectoryRows = parserService.Parse(stream, IParserOptionsRequest.Empty());
|
var trajectoryRows = parserService.Parse(stream, IParserOptionsRequest.Empty());
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ public class TrajectoryParserTest
|
|||||||
Assert.Fail("Файла для импорта не существует");
|
Assert.Fail("Файла для импорта не существует");
|
||||||
|
|
||||||
var parserService = parserServiceFactory.Create<TrajectoryGeoFactDto, IParserOptionsRequest>(
|
var parserService = parserServiceFactory.Create<TrajectoryGeoFactDto, IParserOptionsRequest>(
|
||||||
ParserServiceFactory.IdTrajectoryFactManualParserService);
|
ParserServiceFactory.IdTrajectoryFactManualParser);
|
||||||
|
|
||||||
var trajectoryRows = parserService.Parse(stream, IParserOptionsRequest.Empty());
|
var trajectoryRows = parserService.Parse(stream, IParserOptionsRequest.Empty());
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public class TrajectoryFactManualController : TrajectoryEditableController<Traje
|
|||||||
parserServiceFactory,
|
parserServiceFactory,
|
||||||
trajectoryExportService,
|
trajectoryExportService,
|
||||||
trajectoryRepository,
|
trajectoryRepository,
|
||||||
ParserServiceFactory.IdTrajectoryFactManualParserService)
|
ParserServiceFactory.IdTrajectoryFactManualParser)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,7 +31,7 @@ namespace AsbCloudWebApi.Controllers.Trajectory
|
|||||||
parserServiceFactory,
|
parserServiceFactory,
|
||||||
trajectoryExportService,
|
trajectoryExportService,
|
||||||
trajectoryRepository,
|
trajectoryRepository,
|
||||||
ParserServiceFactory.IdTrajectoryPlanParserService)
|
ParserServiceFactory.IdTrajectoryPlanParser)
|
||||||
{
|
{
|
||||||
this.trajectoryVisualizationService = trajectoryVisualizationService;
|
this.trajectoryVisualizationService = trajectoryVisualizationService;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user