Что было сделано:
-
Был сформирован проект
DataManager
, который предоставляет классParser
, о котором пойдёт речь далее -
В службе при создании обэекта
parsedOptions
формируется сущность опций приложения, которое предоставляет- Ключ для шифрования
- Пути до папки клиента и целевой папки
- Regex выражение, в случае если понадобится изменить формат названия файлов с
Sales_xxxx_xx...
на что-то другое - Формат архивируемого файла
-
Предоставлены интерфейся для создания парсеров и сами парсеры
-
Возможна валидация файла через
.xsd
файл -
Для удобства, как мне показалось, лучше расположить файлы конфигураций в корневой папке, чтобы всё было сразу на виду.
-
Структурирован
appsettings.json
, теперь он разделен наPathsOptions
,EncryptingOptions
иCompressOptions
. С возможностью добавления каких-нибудь опций без особой головной боли.{ "ParseOptions": { "PathsOptions": { "SourceDirectory": "C:\\Users\\Lenovo\\Documents\\GitHub\\CSharp\\ETL project\\SourceDirectory\\", "TargetPath": "C:\\Users\\Lenovo\\Documents\\GitHub\\CSharp\\ETL project\\TargetDirectory\\", "Regex": "Sales_\\d{4}_\\d{2}_\\d{2}_\\d{2}_\\d{2}_\\d{2}\\.txt" }, "EncryptingOptions": { "Key": "b14ca5898a4e4133bbce2ea2315a1916" }, "CompressOptions": { "Extension": ".gz" } } }
отличие этой лабы от второй в том, что мы сами задаём пути до папок, ключи до шифрования и так далее сами через файл. Просто читать это из файла не интересно и не приавльно, так что для удобства в Logger
классе создаётся объект класса Parse
, который делает несколько вещей:
- Он ищет файл
xml
илиjson
и в случае не нахождения кидаетexception
- Он достаёт опции из этого файла и распихивает их по полям объекта
options
Менеджер же конфигураций достаёт нужные нам опции, указанные в ParseOptions
и поставляет их через объект, который позже идёт на разные нужды приложения.
Сами опции парсятся через калссы
XMLParse.cs
иJSONParse.cs
который наследует интерфейсIParse
Что было сделано:
- Во-первых структуризация всего процесса работы с бд
- Теперь есть отдельные
модели
, которые представляют из себя те объекты, которые мы вытягиваем из нашей бд - различные виды служб, которые вы можете найти в папке
ServiceLayer
. Они служат "обёрткой" красивой для работы с шашими таблицами
Любая служба такая наследуется от интерфейса
IRepository
, который и задаёт весь необходимый стандарт качества для наших служб По сути тут используется паттернРепозиторий
, прочитать о нём вы можете тут ->https://habr.com/ru/post/335856/
- В каждом таком репозитории находится конкретный функционал обработки наих обращений к бд и обрабатывается её ответ. Ни в коем случае не хардкодим sql команды, обязательно используем продедуры (вот почему
https://metanit.com/sharp/adonet/2.9.php
)
- Теперь есть отдельные
- Само же обращение к бд,
connectionString
, находится в конфиге приложения и тоже не хардкодится, а настраивается красиво. - Обработка ошибок отведена специальному репозиторию
ErrorService
, который обрабатывает кинутые эксепшены и отправляет их в таблицу dbo.Logs, указывая сообщение ошибки, время ошибки и cамexception
- После обработки полученных из бд данных,
XmlGenerator
генерирует файл Orders.xml (в моём случае), где и лежат все заказы. Или что Вы там обрабатывали - Если же на любом из этапов работы приложения что-то идё не так, то кидается и обрабатывается
exception
- Что бы мы ни писали, мы наследуемся от соответствуещего интерфейса
- Сама ETL разделена на 6 проектов, которые объединяются в
трансформерасолидное приложение.
Что же было сделано:
- Все операции метода ввода-вывода (IO operations), это включает
- Все методы Data Access Layer
- Методы Service Layer , использующие методы DataAccessLaye
- Операции чтения/записи файлов
- Все операции с сетевой передачей данных
- Создаётся ThreadPool на каждую итерацию
Вся суть лабораторной упирается на такой паттерн программрования, как TAP.
По предпоследнему коммиту можно увидеть, где изменился код, в частности функции стали вместо void
возращать Task
. В этих функциях я обернул их работу в await Task.Run(() => {})
, что позволяет по сути нам реализовать необходимый функционал асинхронно, не останавливая работу всего приложения в ожидании завершения синхронного кода.