From 1b87f8baebbe44f840a83e77292bb00063de8586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=A5=D0=B0=D1=80=D0=BB?= =?UTF-8?q?=D0=B0=D0=BC=D0=BE=D0=B2?= Date: Thu, 1 Jun 2023 10:26:44 +0400 Subject: [PATCH 1/6] =?UTF-8?q?=D0=9B=D0=B0=D0=B18=20-=20=D1=82=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=87=D0=BD=D1=8B=D0=B9=20=D0=B2=D1=8B=D0=B2?= =?UTF-8?q?=D0=BE=D0=B4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Attributes/ColumnAttribute.cs | 28 ++++++++++ .../Attributes/GridViewAutoSize.cs | 20 +++++++ .../BindingModels/MessageInfoBindingModel.cs | 1 + .../ViewModels/ClientViewModel.cs | 20 ++++--- .../ViewModels/ComponentViewModel.cs | 16 +++--- .../ViewModels/DishViewModel.cs | 23 +++++--- .../ViewModels/ImplementerViewModel.cs | 12 ++-- .../ViewModels/MessageInfoViewModel.cs | 16 ++++-- .../ViewModels/OrderViewModel.cs | 45 ++++++++------- .../Models/IMessageInfoModel.cs | 2 +- .../Models/MessageInfo.cs | 3 + .../FoodOrders/DataGridViewExtension.cs | 55 +++++++++++++++++++ FoodOrders/FoodOrders/FormClients.cs | 10 +--- FoodOrders/FoodOrders/FormComponents.cs | 29 ++++------ FoodOrders/FoodOrders/FormDish.cs | 3 +- FoodOrders/FoodOrders/FormDishes.cs | 29 ++++------ FoodOrders/FoodOrders/FormImplementers.cs | 8 +-- FoodOrders/FoodOrders/FormMails.cs | 9 +-- FoodOrders/FoodOrders/FormMain.cs | 13 +---- 19 files changed, 216 insertions(+), 126 deletions(-) create mode 100644 FoodOrders/AbstractFoodOrdersContracts/Attributes/ColumnAttribute.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/Attributes/GridViewAutoSize.cs create mode 100644 FoodOrders/FoodOrders/DataGridViewExtension.cs diff --git a/FoodOrders/AbstractFoodOrdersContracts/Attributes/ColumnAttribute.cs b/FoodOrders/AbstractFoodOrdersContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..d2d38e2 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.Attributes +{ + [AttributeUsage(AttributeTargets.Property)] + public class ColumnAttribute : Attribute + { + public ColumnAttribute(string title = "", bool visible = true, int width + = 0, GridViewAutoSize gridViewAutoSize = GridViewAutoSize.None, bool + isUseAutoSize = false) + { + Title = title; + Visible = visible; + Width = width; + GridViewAutoSize = gridViewAutoSize; + IsUseAutoSize = isUseAutoSize; + } + public string Title { get; private set; } + public bool Visible { get; private set; } + public int Width { get; private set; } + public GridViewAutoSize GridViewAutoSize { get; private set; } + public bool IsUseAutoSize { get; private set; } + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/Attributes/GridViewAutoSize.cs b/FoodOrders/AbstractFoodOrdersContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..0d619c2 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + None = 1, + ColumnHeader = 2, + AllCellsExceptHeader = 4, + AllCells = 6, + DisplayedCellsExceptHeader = 8, + DisplayedCells = 10, + Fill = 16 + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/BindingModels/MessageInfoBindingModel.cs b/FoodOrders/AbstractFoodOrdersContracts/BindingModels/MessageInfoBindingModel.cs index 5ec9cd6..4f749c3 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/BindingModels/MessageInfoBindingModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/BindingModels/MessageInfoBindingModel.cs @@ -15,5 +15,6 @@ namespace AbstractFoodOrdersContracts.BindingModels public DateTime DateDelivery { get; set; } public string Subject { get; set; } = string.Empty; public string Body { get; set; } = string.Empty; + public int Id { get; set; } } } diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ClientViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ClientViewModel.cs index 2420e0d..9cd4815 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ClientViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ClientViewModel.cs @@ -1,4 +1,5 @@ -using AbstractFoodOrdersDataModels.Models; +using AbstractFoodOrdersContracts.Attributes; +using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,13 +11,14 @@ namespace AbstractFoodOrdersContracts.ViewModels { public class ClientViewModel:IClientModel { - public int Id { get; set; } - [DisplayName("ФИО клиента")] - public string ClientFIO { get; set; } = string.Empty; - [DisplayName("Логин (эл. почта)")] - public string Email { get; set; } = string.Empty; - [DisplayName("Пароль")] - public string Password { get; set; } = string.Empty; + [Column(visible: false)] + public int Id { get; set; } + [Column(title: "ФИО клиента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string ClientFIO { get; set; } = string.Empty; + [Column(title: "Логин (эл. почта)", width: 200)] + public string Email { get; set; } = string.Empty; + [Column(title: "Пароль", width: 150)] + public string Password { get; set; } = string.Empty; - } + } } diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ComponentViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ComponentViewModel.cs index 1aa5c75..1b11479 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ComponentViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ComponentViewModel.cs @@ -1,4 +1,5 @@ -using AbstractFoodOrdersDataModels.Models; +using AbstractFoodOrdersContracts.Attributes; +using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,11 +11,12 @@ namespace AbstractFoodOrdersContracts.ViewModels { public class ComponentViewModel : IComponentModel { - public int Id { get; set; } - [DisplayName("Название компонента")] - public string ComponentName { get; set; } = string.Empty; - [DisplayName("Цена")] - public double Cost { get; set; } - } + [Column(visible: false)] + public int Id { get; set; } + [Column(title: "Название компонента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string ComponentName { get; set; } = string.Empty; + [Column(title: "Цена", width: 50)] + public double Cost { get; set; } + } } diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/DishViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/DishViewModel.cs index dfab78c..0ffb0e1 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/DishViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/DishViewModel.cs @@ -1,4 +1,5 @@ -using AbstractFoodOrdersDataModels.Models; +using AbstractFoodOrdersContracts.Attributes; +using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,12 +11,18 @@ namespace AbstractFoodOrdersContracts.ViewModels { public class DishViewModel : IDishModel { - public int Id { get; set; } - [DisplayName("Название изделия")] - public string DishName { get; set; } = string.Empty; - [DisplayName("Цена")] - public double Price { get; set; } - public Dictionary DishComponents { get; set; } = new(); - } + [Column(visible: false)] + public int Id { get; set; } + [Column(title: "Название блюда", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string DishName { get; set; } = string.Empty; + [Column(title: "Цена", width: 75)] + public double Price { get; set; } + [Column(visible: false)] + public Dictionary DishComponents + { + get; + set; + } = new(); + } } diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs index 6d592c1..16a76fc 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs @@ -1,4 +1,5 @@ -using AbstractFoodOrdersDataModels.Models; +using AbstractFoodOrdersContracts.Attributes; +using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,14 +11,15 @@ namespace AbstractFoodOrdersContracts.ViewModels { public class ImplementerViewModel:IImplementerModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО")] + [Column(title: "ФИО", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = String.Empty; - [DisplayName("Пароль")] + [Column(title: "Пароль", width: 150)] public string Password { get; set; } = String.Empty; - [DisplayName("Опыт работы")] + [Column(title: "Опыт работы", width: 120)] public int WorkExperience { get; set; } - [DisplayName("Квалификация")] + [Column(title: "Квалификация", width: 120)] public int Qualification { get; set; } } } diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs index 37be3df..6d3f505 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs @@ -1,4 +1,5 @@ -using AbstractFoodOrdersDataModels.Models; +using AbstractFoodOrdersContracts.Attributes; +using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,15 +11,20 @@ namespace AbstractFoodOrdersContracts.ViewModels { public class MessageInfoViewModel:IMessageInfoModel { + [Column(visible: false)] public string MessageId { get; set; } = string.Empty; + [Column(visible: false)] public int? ClientId { get; set; } - [DisplayName("Отправитель")] + [Column(title: "Отправитель", width: 75)] public string SenderName { get; set; } = string.Empty; - [DisplayName("Доставлено")] + [Column(title: "Доставлено")] public DateTime DateDelivery { get; set; } - [DisplayName("Заголовок")] + [Column(title: "Заголовок", width: 75)] public string Subject { get; set; } = string.Empty; - [DisplayName("Текст")] + [Column(title: "Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Body { get; set; } = string.Empty; + + [Column(visible: false)] + public int Id { get; set; } } } diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs index 994623e..fce7a1b 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs @@ -1,4 +1,5 @@ -using AbstractFoodOrdersDataModels.Enums; +using AbstractFoodOrdersContracts.Attributes; +using AbstractFoodOrdersDataModels.Enums; using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; @@ -11,27 +12,31 @@ namespace AbstractFoodOrdersContracts.ViewModels { public class OrderViewModel : IOrderModel { - [DisplayName("Номер")] - public int Id { get; set; } - public int DishId { get; set; } - [DisplayName("Изделие")] - public string DishName { get; set; } = string.Empty; + [Column(title: "Номер")] + public int Id { get; set; } + [Column(visible: false)] + public int DishId { get; set; } + [Column(title: "Блюдо", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string DishName { get; set; } = string.Empty; + [Column(visible: false)] public int? ImplementerId { get; set; } - [DisplayName("Исполнитель")] + [Column(title: "Исполнитель", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string? ImplementerFIO { get; set; } + [Column(visible: false)] public int ClientId { get; set; } - [DisplayName("ФИО клиента")] - public string ClientFIO { get; set; } = string.Empty; + [Column(title: "ФИО клиента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string ClientFIO { get; set; } = string.Empty; + [Column(visible: false)] public string ClientEmail { get; set; } = string.Empty; - [DisplayName("Количество")] - public int Count { get; set; } - [DisplayName("Сумма")] - public double Sum { get; set; } - [DisplayName("Статус")] - public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; - [DisplayName("Дата создания")] - public DateTime DateCreate { get; set; } = DateTime.Now; - [DisplayName("Дата выполнения")] - public DateTime? DateImplement { get; set; } - } + [Column(title: "Количество", width: 100)] + public int Count { get; set; } + [Column(title: "Сумма", width: 100)] + public double Sum { get; set; } + [Column(title: "Статус", width: 125)] + public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; + [Column(title: "Дата создания", width: 120)] + public DateTime DateCreate { get; set; } = DateTime.Now; + [Column(title: "Дата выполнения", width: 120)] + public DateTime? DateImplement { get; set; } + } } diff --git a/FoodOrders/AbstractFoodOrdersDataModels/Models/IMessageInfoModel.cs b/FoodOrders/AbstractFoodOrdersDataModels/Models/IMessageInfoModel.cs index 668b834..730e5a9 100644 --- a/FoodOrders/AbstractFoodOrdersDataModels/Models/IMessageInfoModel.cs +++ b/FoodOrders/AbstractFoodOrdersDataModels/Models/IMessageInfoModel.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace AbstractFoodOrdersDataModels.Models { - public interface IMessageInfoModel + public interface IMessageInfoModel:IId { string MessageId { get; } int? ClientId { get; } diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs index a677df4..3fe1ed4 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs @@ -26,6 +26,9 @@ namespace AbstractFoodOrdersDatabaseImplement.Models [Required] public string Body { get; set; } = string.Empty; + [NotMapped] + public int Id { get; private set; } + public static MessageInfo? Create(MessageInfoBindingModel model) { if (model == null) diff --git a/FoodOrders/FoodOrders/DataGridViewExtension.cs b/FoodOrders/FoodOrders/DataGridViewExtension.cs new file mode 100644 index 0000000..19db3ae --- /dev/null +++ b/FoodOrders/FoodOrders/DataGridViewExtension.cs @@ -0,0 +1,55 @@ +using AbstractFoodOrdersContracts.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FoodOrders +{ + public static class DataGridViewExtension + { + public static void FillAndConfigGrid(this DataGridView grid, List? data) + { + if (data == null) + { + return; + } + grid.DataSource = data; + var type = typeof(T); + var properties = type.GetProperties(); + foreach (DataGridViewColumn column in grid.Columns) + { + var property = properties.FirstOrDefault(x => x.Name == + column.Name); + if (property == null) + { + throw new InvalidOperationException($"В типе {type.Name} не найдено свойство с именем { column.Name }"); + } + var attribute = + property.GetCustomAttributes(typeof(ColumnAttribute), true)?.SingleOrDefault(); + if (attribute == null) + { + throw new InvalidOperationException($"Не найден атрибут тип ColumnAttribute для свойства { property.Name }"); + } + // ищем нужный нам атрибут + if (attribute is ColumnAttribute columnAttr) + { + column.HeaderText = columnAttr.Title; + column.Visible = columnAttr.Visible; + if (columnAttr.IsUseAutoSize) + { + column.AutoSizeMode = + (DataGridViewAutoSizeColumnMode)Enum.Parse(typeof(DataGridViewAutoSizeColumnMode) + , columnAttr.GridViewAutoSize.ToString()); + } + else + { + column.Width = columnAttr.Width; + } + } + } + } + + } +} diff --git a/FoodOrders/FoodOrders/FormClients.cs b/FoodOrders/FoodOrders/FormClients.cs index 72e82e3..758b1eb 100644 --- a/FoodOrders/FoodOrders/FormClients.cs +++ b/FoodOrders/FoodOrders/FormClients.cs @@ -32,15 +32,9 @@ namespace FoodOrders private void LoadData() { - try + try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridViewClients.DataSource = list; - dataGridViewClients.Columns["Id"].Visible = false; - dataGridViewClients.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridViewClients.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка клиентов"); } catch (Exception ex) diff --git a/FoodOrders/FoodOrders/FormComponents.cs b/FoodOrders/FoodOrders/FormComponents.cs index 17680cc..4a1577e 100644 --- a/FoodOrders/FoodOrders/FormComponents.cs +++ b/FoodOrders/FoodOrders/FormComponents.cs @@ -30,24 +30,17 @@ namespace FoodOrders } private void LoadData() { - try - { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } - _logger.LogInformation("Загрузка компонентов"); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка загрузки компонентов"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, - MessageBoxIcon.Error); - } - } + try + { + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка компонентов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки компонент"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } private void ButtonAdd_Click(object sender, EventArgs e) { var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); diff --git a/FoodOrders/FoodOrders/FormDish.cs b/FoodOrders/FoodOrders/FormDish.cs index 41bf6c7..c4d583c 100644 --- a/FoodOrders/FoodOrders/FormDish.cs +++ b/FoodOrders/FoodOrders/FormDish.cs @@ -38,8 +38,7 @@ namespace FoodOrders { var view = _logic.ReadElement(new DishSearchModel { - Id = - _id.Value + Id = _id.Value }); if (view != null) { diff --git a/FoodOrders/FoodOrders/FormDishes.cs b/FoodOrders/FoodOrders/FormDishes.cs index d7edcc9..50c050a 100644 --- a/FoodOrders/FoodOrders/FormDishes.cs +++ b/FoodOrders/FoodOrders/FormDishes.cs @@ -32,24 +32,17 @@ namespace FoodOrders private void LoadData() { - try - { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["DishComponents"].Visible = false; - dataGridView.Columns["DishName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } - _logger.LogInformation("Загрузка изделий"); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка загрузки изделий"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } + try + { + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка изделий"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки изделий"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } private void buttonAdd_Click(object sender, EventArgs e) { diff --git a/FoodOrders/FoodOrders/FormImplementers.cs b/FoodOrders/FoodOrders/FormImplementers.cs index 312ae9e..d3ee27b 100644 --- a/FoodOrders/FoodOrders/FormImplementers.cs +++ b/FoodOrders/FoodOrders/FormImplementers.cs @@ -33,13 +33,7 @@ namespace FoodOrders { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка исполнителей"); } catch (Exception ex) diff --git a/FoodOrders/FoodOrders/FormMails.cs b/FoodOrders/FoodOrders/FormMails.cs index d1ed859..b7cc14b 100644 --- a/FoodOrders/FoodOrders/FormMails.cs +++ b/FoodOrders/FoodOrders/FormMails.cs @@ -27,14 +27,7 @@ namespace FoodOrders { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["MessageId"].Visible = false; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка писем"); } catch (Exception ex) diff --git a/FoodOrders/FoodOrders/FormMain.cs b/FoodOrders/FoodOrders/FormMain.cs index a224318..c97a32d 100644 --- a/FoodOrders/FoodOrders/FormMain.cs +++ b/FoodOrders/FoodOrders/FormMain.cs @@ -34,22 +34,15 @@ namespace FoodOrders } private void LoadData() { + try { - var list = _orderLogic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["DishId"].Visible = false; - dataGridView.Columns["ImplementerId"].Visible = false; - dataGridView.Columns["ClientEmail"].Visible = false; - } + dataGridView.FillAndConfigGrid(_orderLogic.ReadList(null)); _logger.LogInformation("Загрузка заказов"); } catch (Exception ex) { - _logger.LogError(ex, "Ошибка загрузки заказов"); + _logger.LogError(ex, "Ошибка загрузки изделий"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } } -- 2.25.1 From 2f5dbdfd5bdb3b0c246bbbf2d05832f55acfbfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=A5=D0=B0=D1=80=D0=BB?= =?UTF-8?q?=D0=B0=D0=BC=D0=BE=D0=B2?= Date: Thu, 1 Jun 2023 16:18:23 +0400 Subject: [PATCH 2/6] =?UTF-8?q?=D0=9B=D0=B0=D0=B18=20-=20=D0=B1=D0=B5?= =?UTF-8?q?=D0=BA=D0=B0=D0=BF=20=D0=B8=20=D0=BD=D0=B0=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D0=BA=D0=B0=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8?= =?UTF-8?q?=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/MessageInfoStorage.cs | 77 +++++++++++++++++++ .../ListImplementationExtension.cs | 26 +++++++ .../Models/MessageInfo.cs | 49 ++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs create mode 100644 FoodOrders/AbstractFoodOrdersListImplement/ListImplementationExtension.cs create mode 100644 FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs diff --git a/FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs b/FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs new file mode 100644 index 0000000..956e02f --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs @@ -0,0 +1,77 @@ +using AbstractFoodOrdersContracts.BindingModels; +using AbstractFoodOrdersContracts.SearchModels; +using AbstractFoodOrdersContracts.StoragesContracts; +using AbstractFoodOrdersContracts.ViewModels; +using AbstractFoodOrdersListImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersListImplement.Implements +{ + public class MessageInfoStorage:IMessageInfoStorage + { + private readonly DataListSingleton _source; + + public MessageInfoStorage(DataListSingleton source) + { + _source = source; + } + + public List GetFullList() + { + var result = new List(); + foreach (var messageInfo in _source.MessageInfos) + { + result.Add(messageInfo.GetViewModel); + } + return result; + } + + public List GetFilteredList(MessageInfoSearchModel model) + { + var result = new List(); + if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue) + { + return result; + } + foreach (var messageInfo in _source.MessageInfos) + { + if (messageInfo.ClientId == model.ClientId) + { + result.Add(messageInfo.GetViewModel); + } + } + return result; + } + + public MessageInfoViewModel? GetElement(MessageInfoSearchModel model) + { + if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue) + { + return null; + } + foreach (var messageInfo in _source.MessageInfos) + { + if (!string.IsNullOrEmpty(model.MessageId) && model.ClientId.HasValue && messageInfo.MessageId == model.MessageId && messageInfo.ClientId == model.ClientId) + { + return messageInfo.GetViewModel; + } + } + return null; + } + + public MessageInfoViewModel? Insert(MessageInfoBindingModel model) + { + var newMessageInfo = MessageInfo.Create(model); + if (newMessageInfo == null) + { + return null; + } + _source.MessageInfos.Add(newMessageInfo); + return newMessageInfo.GetViewModel; + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersListImplement/ListImplementationExtension.cs b/FoodOrders/AbstractFoodOrdersListImplement/ListImplementationExtension.cs new file mode 100644 index 0000000..3abe622 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersListImplement/ListImplementationExtension.cs @@ -0,0 +1,26 @@ +using AbstractFoodOrdersContracts.DI; +using AbstractFoodOrdersContracts.StoragesContracts; +using AbstractFoodOrdersListImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersListImplement +{ + public class ListImplementationExtension : IImplementationExtension + { + public int Priority => 0; + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs b/FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs new file mode 100644 index 0000000..ac8ef4e --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs @@ -0,0 +1,49 @@ +using AbstractFoodOrdersContracts.BindingModels; +using AbstractFoodOrdersContracts.ViewModels; +using AbstractFoodOrdersDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersListImplement.Models +{ + public class MessageInfo:IMessageInfoModel + { + public string MessageId { get; set; } = string.Empty; + public int? ClientId { get; set; } + public string SenderName { get; set; } = string.Empty; + public DateTime DateDelivery { get; set; } + public string Subject { get; set; } = string.Empty; + public string Body { get; set; } = string.Empty; + public int Id { get; private set; } + + public static MessageInfo? Create(MessageInfoBindingModel model) + { + if (model == null) + { + return null; + } + return new MessageInfo() + { + MessageId = model.MessageId, + ClientId = model.ClientId, + SenderName = model.SenderName, + Body = model.Body, + Subject = model.Subject, + DateDelivery = model.DateDelivery + }; + } + + public MessageInfoViewModel GetViewModel => new() + { + MessageId = MessageId, + ClientId = ClientId, + SenderName = SenderName, + Body = Body, + Subject = Subject, + DateDelivery = DateDelivery + }; + } +} -- 2.25.1 From e66180e3a4797fbbb2d2c35f417bd78e723fcb98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=A5=D0=B0=D1=80=D0=BB?= =?UTF-8?q?=D0=B0=D0=BC=D0=BE=D0=B2?= Date: Thu, 1 Jun 2023 16:18:44 +0400 Subject: [PATCH 3/6] =?UTF-8?q?=D0=9B=D0=B0=D0=B18=20-=20=D0=B1=D0=B5?= =?UTF-8?q?=D0=BA=D0=B0=D0=BF=20=D0=B8=20=D0=BD=D0=B0=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D0=BA=D0=B0=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8?= =?UTF-8?q?=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/BackUpLogic.cs | 105 +++++++ .../AbstractFoodOrdersContracts.csproj | 2 + .../BindingModels/BackUpSaveBinidngModel.cs | 13 + .../BusinessLogicsContracts/IBackUpLogic.cs | 14 + .../DI/DependencyManager.cs | 60 ++++ .../DI/IDependencyContainer.cs | 41 +++ .../DI/IImplementationExtension.cs | 20 ++ .../DI/ServiceDependencyContainer.cs | 62 ++++ .../DI/ServiceProviderLoader.cs | 66 ++++ .../DI/UnityDependencyContainer.cs | 55 ++++ .../StoragesContracts/IBackUpInfo.cs | 14 + .../ViewModels/ImplementerViewModel.cs | 2 +- .../ViewModels/MessageInfoViewModel.cs | 4 +- .../ViewModels/OrderViewModel.cs | 10 +- ...AbstractFoodOrdersDatabaseImplement.csproj | 4 + .../DatabaseImplementationExtension.cs | 27 ++ .../Implements/BackUpInfo.cs | 32 ++ ...230601100316_MessageInfoUpdate.Designer.cs | 285 ++++++++++++++++++ .../20230601100316_MessageInfoUpdate.cs | 22 ++ .../Models/Client.cs | 16 +- .../Models/Component.cs | 13 +- .../Models/Dish.cs | 11 +- .../Models/Implementer.cs | 6 + .../Models/MessageInfo.cs | 8 + .../Models/Order.cs | 24 +- .../AbstractFoodOrdersListImplement.csproj | 4 + .../AbstractFoodOrdersFileImplement.csproj | 4 + .../DataFileSingleton.cs | 92 +++--- .../FileImplementationExtension.cs | 27 ++ .../Implements/BackUpInfo.cs | 43 +++ .../Implements/OrderStorage.cs | 111 +++---- .../Models/Client.cs | 14 +- .../Models/Component.cs | 11 +- .../AbstractShopFileImplement/Models/Dish.cs | 11 +- .../Models/Implementer.cs | 10 +- .../Models/MessageInfo.cs | 9 + .../AbstractShopFileImplement/Models/Order.cs | 164 +++++----- FoodOrders/FoodOrders/FormComponents.cs | 40 ++- FoodOrders/FoodOrders/FormDish.cs | 19 +- FoodOrders/FoodOrders/FormDishes.cs | 39 ++- FoodOrders/FoodOrders/FormImplementers.cs | 21 +- FoodOrders/FoodOrders/FormMain.Designer.cs | 31 +- FoodOrders/FoodOrders/FormMain.cs | 138 +++------ FoodOrders/FoodOrders/Program.cs | 121 ++++---- .../AbstractFoodOrdersContracts.dll | Bin 0 -> 31744 bytes .../AbstractFoodOrdersDataModels.dll | Bin 0 -> 6656 bytes .../AbstractFoodOrdersFileImplement.dll | Bin 0 -> 40448 bytes .../AbstractFoodOrdersListImplement.dll | Bin 0 -> 26112 bytes 48 files changed, 1362 insertions(+), 463 deletions(-) create mode 100644 FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/BindingModels/BackUpSaveBinidngModel.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/DI/DependencyManager.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/DI/IDependencyContainer.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/DI/IImplementationExtension.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/DI/ServiceDependencyContainer.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/DI/ServiceProviderLoader.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/DI/UnityDependencyContainer.cs create mode 100644 FoodOrders/AbstractFoodOrdersContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 FoodOrders/AbstractFoodOrdersDatabaseImplement/DatabaseImplementationExtension.cs create mode 100644 FoodOrders/AbstractFoodOrdersDatabaseImplement/Implements/BackUpInfo.cs create mode 100644 FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.Designer.cs create mode 100644 FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.cs create mode 100644 FoodOrders/AbstractShopFileImplement/FileImplementationExtension.cs create mode 100644 FoodOrders/AbstractShopFileImplement/Implements/BackUpInfo.cs create mode 100644 FoodOrders/ImplementationExtensions/AbstractFoodOrdersContracts.dll create mode 100644 FoodOrders/ImplementationExtensions/AbstractFoodOrdersDataModels.dll create mode 100644 FoodOrders/ImplementationExtensions/AbstractFoodOrdersFileImplement.dll create mode 100644 FoodOrders/ImplementationExtensions/AbstractFoodOrdersListImplement.dll diff --git a/FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs b/FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs new file mode 100644 index 0000000..b6a3906 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs @@ -0,0 +1,105 @@ +using AbstractFoodOrdersContracts.BindingModels; +using AbstractFoodOrdersContracts.BusinessLogicsContracts; +using AbstractFoodOrdersContracts.StoragesContracts; +using AbstractFoodOrdersDataModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.IO.Compression; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersBusinessLogic.BusinessLogics +{ + public class BackUpLogic : IBackUpLogic + { + private readonly ILogger _logger; + private readonly IBackUpInfo _backUpInfo; + public BackUpLogic(ILogger logger, IBackUpInfo backUpInfo) + { + _logger = logger; + _backUpInfo = backUpInfo; + } + public void CreateBackUp(BackUpSaveBinidngModel model) + { + if (_backUpInfo == null) + { + return; + } + try + { + _logger.LogDebug("Clear folder"); + // зачистка папки и удаление старого архива + var dirInfo = new DirectoryInfo(model.FolderName); + if (dirInfo.Exists) + { + foreach (var file in dirInfo.GetFiles()) + { + file.Delete(); + } + } + _logger.LogDebug("Delete archive"); + string fileName = $"{model.FolderName}.zip"; + if (File.Exists(fileName)) + { + File.Delete(fileName); + } + // берем метод для сохранения + _logger.LogDebug("Get assembly"); + var typeIId = typeof(IId); + var assembly = typeIId.Assembly; + if (assembly == null) + { + throw new ArgumentNullException("Сборка не найдена", + nameof(assembly)); + } + var types = assembly.GetTypes(); + var method = GetType().GetMethod("SaveToFile", + BindingFlags.NonPublic | BindingFlags.Instance); + _logger.LogDebug("Find {count} types", types.Length); + foreach (var type in types) + { + if (type.IsInterface && type.GetInterface(typeIId.Name) != + null) + { + var modelType = + _backUpInfo.GetTypeByModelInterface(type.Name); + if (modelType == null) + { + throw new InvalidOperationException($"Не найден класс - модель для { type.Name }"); + } + _logger.LogDebug("Call SaveToFile method for {name} type", type.Name); + // вызываем метод на выполнение + method?.MakeGenericMethod(modelType).Invoke(this, new + object[] { model.FolderName }); + } + } + _logger.LogDebug("Create zip and remove folder"); + // архивируем + ZipFile.CreateFromDirectory(model.FolderName, fileName); + // удаляем папку + dirInfo.Delete(true); + } + catch (Exception) + { + throw; + } + } + private void SaveToFile(string folderName) where T : class, new() + { + var records = _backUpInfo.GetList(); + if (records == null) + { + _logger.LogWarning("{type} type get null list", typeof(T).Name); + return; + } + var jsonFormatter = new DataContractJsonSerializer(typeof(List)); + using var fs = new FileStream(string.Format("{0}/{1}.json", + folderName, typeof(T).Name), FileMode.OpenOrCreate); + jsonFormatter.WriteObject(fs, records); + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/AbstractFoodOrdersContracts.csproj b/FoodOrders/AbstractFoodOrdersContracts/AbstractFoodOrdersContracts.csproj index 334fa22..87652d7 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/AbstractFoodOrdersContracts.csproj +++ b/FoodOrders/AbstractFoodOrdersContracts/AbstractFoodOrdersContracts.csproj @@ -9,6 +9,8 @@ + + diff --git a/FoodOrders/AbstractFoodOrdersContracts/BindingModels/BackUpSaveBinidngModel.cs b/FoodOrders/AbstractFoodOrdersContracts/BindingModels/BackUpSaveBinidngModel.cs new file mode 100644 index 0000000..0596d2f --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/BindingModels/BackUpSaveBinidngModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.BindingModels +{ + public class BackUpSaveBinidngModel + { + public string FolderName { get; set; } = string.Empty; + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/BusinessLogicsContracts/IBackUpLogic.cs b/FoodOrders/AbstractFoodOrdersContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..b797302 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,14 @@ +using AbstractFoodOrdersContracts.BindingModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBinidngModel model); + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/DI/DependencyManager.cs b/FoodOrders/AbstractFoodOrdersContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..8232090 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/DI/DependencyManager.cs @@ -0,0 +1,60 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.DI +{ + /// + /// Менеджер для работы с зависимостями + /// + public class DependencyManager + { + private readonly IDependencyContainer _dependencyManager; + + private static DependencyManager? _manager; + + private static readonly object _locjObject = new(); + + private DependencyManager() + { + _dependencyManager = new UnityDependencyContainer(); + } + + public static DependencyManager Instance + { + get + { + if (_manager == null) + { + lock (_locjObject) + { + _manager = new DependencyManager(); + } + } + return _manager; + } + } + + public static void InitDependency() + { + var ext = ServiceProviderLoader.GetImplementationExtensions(); + if (ext == null) + { + throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям"); + } + ext.RegisterServices(); + } + + public void AddLogging(Action configure) => _dependencyManager.AddLogging(configure); + + public void RegisterType(bool isSingle = false) where U : class, T where T : class => _dependencyManager.RegisterType(isSingle); + + public void RegisterType(bool isSingle = false) where T : class => _dependencyManager.RegisterType(isSingle); + + public T Resolve() => _dependencyManager.Resolve(); + } + +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/DI/IDependencyContainer.cs b/FoodOrders/AbstractFoodOrdersContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..711f29a --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/DI/IDependencyContainer.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.DI +{ + /// + /// Интерфейс установки зависмости между элементами + /// + public interface IDependencyContainer + { + /// + /// Регистрация логгера + /// + /// + void AddLogging(Action configure); + /// + /// Добавление зависимости + /// + /// + /// + /// + void RegisterType(bool isSingle) where U : class, T where T : + class; + /// + /// Добавление зависимости + /// + /// + /// + void RegisterType(bool isSingle) where T : class; + /// + /// Получение класса со всеми зависмостями + /// + /// + /// + T Resolve(); + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/DI/IImplementationExtension.cs b/FoodOrders/AbstractFoodOrdersContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..4ba3344 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/DI/IImplementationExtension.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.DI +{ + /// + /// Интерфейс для регистрации зависимостей в модулях + /// + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/DI/ServiceDependencyContainer.cs b/FoodOrders/AbstractFoodOrdersContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..b6dcf99 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/DI/ServiceDependencyContainer.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.DI +{ + public class ServiceDependencyContainer : IDependencyContainer + { + private ServiceProvider? _serviceProvider; + + private readonly ServiceCollection _serviceCollection; + + public ServiceDependencyContainer() + { + _serviceCollection = new ServiceCollection(); + } + + public void AddLogging(Action configure) + { + _serviceCollection.AddLogging(configure); + } + + public void RegisterType(bool isSingle) where U : class, T where T : class + { + if (isSingle) + { + _serviceCollection.AddSingleton(); + } + else + { + _serviceCollection.AddTransient(); + } + _serviceProvider = null; + } + + public void RegisterType(bool isSingle) where T : class + { + if (isSingle) + { + _serviceCollection.AddSingleton(); + } + else + { + _serviceCollection.AddTransient(); + } + _serviceProvider = null; + } + + public T Resolve() + { + if (_serviceProvider == null) + { + _serviceProvider = _serviceCollection.BuildServiceProvider(); + } + return _serviceProvider.GetService()!; + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/DI/ServiceProviderLoader.cs b/FoodOrders/AbstractFoodOrdersContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..23edf71 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.DI +{ + /// + /// Загрузчик данных + /// + public static partial class ServiceProviderLoader + { + /// + /// Загрузка всех классов-реализаций IImplementationExtension + /// + /// + public static IImplementationExtension? GetImplementationExtensions() + { + IImplementationExtension? source = null; + var files = + Directory.GetFiles(TryGetImplementationExtensionsFolder(), "*.dll", + SearchOption.AllDirectories); + foreach (var file in files.Distinct()) + { + Assembly asm = Assembly.LoadFrom(file); + foreach (var t in asm.GetExportedTypes()) + { + if (t.IsClass && + typeof(IImplementationExtension).IsAssignableFrom(t)) + { + if (source == null) + { + source = + (IImplementationExtension)Activator.CreateInstance(t)!; + } + else + { + var newSource = + (IImplementationExtension)Activator.CreateInstance(t)!; + if (newSource.Priority > + source.Priority) + { + source = newSource; + } + } + } + } + } + return source; + } + private static string TryGetImplementationExtensionsFolder() + { + var directory = new + DirectoryInfo(Directory.GetCurrentDirectory()); + while (directory != null && + !directory.GetDirectories("ImplementationExtensions", + SearchOption.AllDirectories).Any(x => x.Name == "ImplementationExtensions")) + { + directory = directory.Parent; + } + return $"{directory?.FullName}\\ImplementationExtensions"; + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/DI/UnityDependencyContainer.cs b/FoodOrders/AbstractFoodOrdersContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..e9c4691 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,55 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unity; +using Unity.Microsoft.Logging; + +namespace AbstractFoodOrdersContracts.DI +{ + public class UnityDependencyContainer : IDependencyContainer + { + private readonly UnityContainer _unityContainer; + + public UnityDependencyContainer() + { + _unityContainer = new UnityContainer(); + } + + public void AddLogging(Action configure) + { + _unityContainer.AddExtension(new LoggingExtension(LoggerFactory.Create(configure))); + } + + public void RegisterType(bool isSingle) where U : class, T where T : class + { + if (isSingle) + { + _unityContainer.RegisterSingleton(); + } + else + { + _unityContainer.RegisterType(); + } + } + + public void RegisterType(bool isSingle) where T : class + { + if (isSingle) + { + _unityContainer.RegisterSingleton(); + } + else + { + _unityContainer.RegisterType(); + } + } + + public T Resolve() + { + return _unityContainer.Resolve(); + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/StoragesContracts/IBackUpInfo.cs b/FoodOrders/AbstractFoodOrdersContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..6d8dd61 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs index 16a76fc..e9500d4 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/ImplementerViewModel.cs @@ -13,7 +13,7 @@ namespace AbstractFoodOrdersContracts.ViewModels { [Column(visible: false)] public int Id { get; set; } - [Column(title: "ФИО", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + [Column(title: "ФИО", width: 150)] public string ImplementerFIO { get; set; } = String.Empty; [Column(title: "Пароль", width: 150)] public string Password { get; set; } = String.Empty; diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs index 6d3f505..721771e 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/MessageInfoViewModel.cs @@ -15,9 +15,9 @@ namespace AbstractFoodOrdersContracts.ViewModels public string MessageId { get; set; } = string.Empty; [Column(visible: false)] public int? ClientId { get; set; } - [Column(title: "Отправитель", width: 75)] + [Column(title: "Отправитель", width: 100)] public string SenderName { get; set; } = string.Empty; - [Column(title: "Доставлено")] + [Column(title: "Доставлено", width: 100)] public DateTime DateDelivery { get; set; } [Column(title: "Заголовок", width: 75)] public string Subject { get; set; } = string.Empty; diff --git a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs index fce7a1b..c049cc6 100644 --- a/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs +++ b/FoodOrders/AbstractFoodOrdersContracts/ViewModels/OrderViewModel.cs @@ -12,19 +12,19 @@ namespace AbstractFoodOrdersContracts.ViewModels { public class OrderViewModel : IOrderModel { - [Column(title: "Номер")] + [Column(title: "Номер", width: 80)] public int Id { get; set; } [Column(visible: false)] public int DishId { get; set; } - [Column(title: "Блюдо", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + [Column(title: "Блюдо", width: 90)] public string DishName { get; set; } = string.Empty; [Column(visible: false)] public int? ImplementerId { get; set; } - [Column(title: "Исполнитель", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + [Column(title: "Исполнитель", width: 120)] public string? ImplementerFIO { get; set; } [Column(visible: false)] public int ClientId { get; set; } - [Column(title: "ФИО клиента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + [Column(title: "ФИО клиента", width: 120)] public string ClientFIO { get; set; } = string.Empty; [Column(visible: false)] public string ClientEmail { get; set; } = string.Empty; @@ -32,7 +32,7 @@ namespace AbstractFoodOrdersContracts.ViewModels public int Count { get; set; } [Column(title: "Сумма", width: 100)] public double Sum { get; set; } - [Column(title: "Статус", width: 125)] + [Column(title: "Статус", width: 100)] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; [Column(title: "Дата создания", width: 120)] public DateTime DateCreate { get; set; } = DateTime.Now; diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/AbstractFoodOrdersDatabaseImplement.csproj b/FoodOrders/AbstractFoodOrdersDatabaseImplement/AbstractFoodOrdersDatabaseImplement.csproj index 17b6b3f..17119ff 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/AbstractFoodOrdersDatabaseImplement.csproj +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/AbstractFoodOrdersDatabaseImplement.csproj @@ -20,4 +20,8 @@ + + + + diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/DatabaseImplementationExtension.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/DatabaseImplementationExtension.cs new file mode 100644 index 0000000..fa04af5 --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/DatabaseImplementationExtension.cs @@ -0,0 +1,27 @@ +using AbstractFoodOrdersContracts.DI; +using AbstractFoodOrdersContracts.StoragesContracts; +using AbstractFoodOrdersDatabaseImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersDatabaseImplement +{ + public class DatabaseImplementationExtension : IImplementationExtension + { + public int Priority => 2; + + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Implements/BackUpInfo.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..92efd6a --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Implements/BackUpInfo.cs @@ -0,0 +1,32 @@ +using AbstractFoodOrdersContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersDatabaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new AbstractFoodOrdersDatabase(); + return context.Set().ToList(); + } + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + var assembly = typeof(BackUpInfo).Assembly; + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsClass && + type.GetInterface(modelInterfaceName) != null) + { + return type; + } + } + return null; + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.Designer.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.Designer.cs new file mode 100644 index 0000000..8dd78bf --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.Designer.cs @@ -0,0 +1,285 @@ +// +using System; +using AbstractFoodOrdersDatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AbstractFoodOrdersDatabaseImplement.Migrations +{ + [DbContext(typeof(AbstractFoodOrdersDatabase))] + [Migration("20230601100316_MessageInfoUpdate")] + partial class MessageInfoUpdate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cost") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Dish", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DishName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Dishes"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.DishComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DishId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("DishId"); + + b.ToTable("DishComponents"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Qualification") + .HasColumnType("int"); + + b.Property("WorkExperience") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.MessageInfo", b => + { + b.Property("MessageId") + .HasColumnType("nvarchar(450)"); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("DateDelivery") + .HasColumnType("datetime2"); + + b.Property("SenderName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("MessageId"); + + b.ToTable("MessageInfos"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DateCreate") + .HasColumnType("datetime2"); + + b.Property("DateImplement") + .HasColumnType("datetime2"); + + b.Property("DishId") + .HasColumnType("int"); + + b.Property("ImplementerId") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Sum") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.HasIndex("DishId"); + + b.HasIndex("ImplementerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.DishComponent", b => + { + b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Component", "Component") + .WithMany("DishComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Dish", "Dish") + .WithMany("Components") + .HasForeignKey("DishId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Dish"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Order", b => + { + b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Client", "Client") + .WithMany("ClientOrders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Dish", "Dish") + .WithMany("Orders") + .HasForeignKey("DishId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Implementer", "Implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerId"); + + b.Navigation("Client"); + + b.Navigation("Dish"); + + b.Navigation("Implementer"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Client", b => + { + b.Navigation("ClientOrders"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Component", b => + { + b.Navigation("DishComponents"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Dish", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.cs new file mode 100644 index 0000000..964f62b --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Migrations/20230601100316_MessageInfoUpdate.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AbstractFoodOrdersDatabaseImplement.Migrations +{ + /// + public partial class MessageInfoUpdate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Client.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Client.cs index 2adcc17..7d87d7f 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Client.cs +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Client.cs @@ -6,19 +6,25 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace AbstractFoodOrdersDatabaseImplement.Models { - public class Client:IClientModel + [DataContract] + public class Client:IClientModel { - public int Id { get; set; } - [Required] + [DataMember] + public int Id { get; set; } + [DataMember] + [Required] public string ClientFIO { get; private set; } = string.Empty; - [Required] + [DataMember] + [Required] public string Password { get; set; } = string.Empty; - [Required] + [DataMember] + [Required] public string Email { get; private set; } = string.Empty; [ForeignKey("ClientId")] public virtual List ClientOrders { get; set; } = new(); diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Component.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Component.cs index 80508fa..78ce8c3 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Component.cs +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Component.cs @@ -3,15 +3,20 @@ using AbstractFoodOrdersContracts.ViewModels; using AbstractFoodOrdersDataModels.Models; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace AbstractFoodOrdersDatabaseImplement.Models { - public class Component : IComponentModel + [DataContract] + public class Component : IComponentModel { - public int Id { get; private set; } - [Required] + [DataMember] + public int Id { get; private set; } + [DataMember] + [Required] public string ComponentName { get; private set; } = string.Empty; - [Required] + [DataMember] + [Required] public double Cost { get; set; } [ForeignKey("ComponentId")] public virtual List DishComponents { get; set; } = new(); diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Dish.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Dish.cs index 7862f7c..c7cf852 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Dish.cs +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Dish.cs @@ -8,15 +8,20 @@ using System.Text; using System.Threading.Tasks; using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.ViewModels; +using System.Runtime.Serialization; namespace AbstractFoodOrdersDatabaseImplement.Models { + [DataContract] public class Dish : IDishModel { - public int Id { get; set; } - [Required] + [DataMember] + public int Id { get; set; } + [DataMember] + [Required] public string DishName { get; set; } = string.Empty; - [Required] + [DataMember] + [Required] public double Price { get; set; } private Dictionary? _dishComponents = null; [NotMapped] diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Implementer.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Implementer.cs index 996bcc8..728183a 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Implementer.cs +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Implementer.cs @@ -8,18 +8,24 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.Serialization; namespace AbstractFoodOrdersDatabaseImplement.Models { public class Implementer:IImplementerModel { + [DataMember] public int Id { get; private set; } + [DataMember] [Required] public string ImplementerFIO { get; set; } = string.Empty; + [DataMember] [Required] public string Password { get; set; } = string.Empty; + [DataMember] [Required] public int WorkExperience { get; set; } + [DataMember] [Required] public int Qualification { get; set; } [ForeignKey("ImplementerId")] diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs index 3fe1ed4..0523105 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/MessageInfo.cs @@ -8,21 +8,29 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.Serialization; namespace AbstractFoodOrdersDatabaseImplement.Models { + [DataContract] public class MessageInfo:IMessageInfoModel { + [DataMember] [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public string MessageId { get; set; } = string.Empty; + [DataMember] public int? ClientId { get; set; } + [DataMember] [Required] public string SenderName { get; set; } = string.Empty; + [DataMember] [Required] public DateTime DateDelivery { get; set; } + [DataMember] [Required] public string Subject { get; set; } = string.Empty; + [DataMember] [Required] public string Body { get; set; } = string.Empty; diff --git a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Order.cs b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Order.cs index d6b4958..a3f9bc4 100644 --- a/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Order.cs +++ b/FoodOrders/AbstractFoodOrdersDatabaseImplement/Models/Order.cs @@ -7,6 +7,7 @@ using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; @@ -14,23 +15,32 @@ namespace AbstractFoodOrdersDatabaseImplement.Models { public class Order : IOrderModel { - public int Id { get; private set; } - [Required] + [DataMember] + public int Id { get; private set; } + [DataMember] + [Required] public int DishId { get; private set; } - [Required] + [DataMember] + [Required] public int ClientId { get; set; } public virtual Client Client { get; set; } = new(); + [DataMember] public int? ImplementerId { get; set; } public virtual Implementer? Implementer { get; set; } = new(); + [DataMember] [Required] public int Count { get; private set; } - [Required] + [DataMember] + [Required] public double Sum { get; private set; } - [Required] + [DataMember] + [Required] public OrderStatus Status { get; private set; } - [Required] + [DataMember] + [Required] public DateTime DateCreate { get; private set; } - public DateTime? DateImplement { get; private set; } + [DataMember] + public DateTime? DateImplement { get; private set; } public virtual Dish Dish { get; set; } public static Order? Create(AbstractFoodOrdersDatabase data, OrderBindingModel? model) { diff --git a/FoodOrders/AbstractFoodOrdersListImplement/AbstractFoodOrdersListImplement.csproj b/FoodOrders/AbstractFoodOrdersListImplement/AbstractFoodOrdersListImplement.csproj index 6c08ca5..1ccf37d 100644 --- a/FoodOrders/AbstractFoodOrdersListImplement/AbstractFoodOrdersListImplement.csproj +++ b/FoodOrders/AbstractFoodOrdersListImplement/AbstractFoodOrdersListImplement.csproj @@ -16,4 +16,8 @@ + + + + diff --git a/FoodOrders/AbstractShopFileImplement/AbstractFoodOrdersFileImplement.csproj b/FoodOrders/AbstractShopFileImplement/AbstractFoodOrdersFileImplement.csproj index 9d405d7..39c68e0 100644 --- a/FoodOrders/AbstractShopFileImplement/AbstractFoodOrdersFileImplement.csproj +++ b/FoodOrders/AbstractShopFileImplement/AbstractFoodOrdersFileImplement.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/FoodOrders/AbstractShopFileImplement/DataFileSingleton.cs b/FoodOrders/AbstractShopFileImplement/DataFileSingleton.cs index 06c2bfb..0144a57 100644 --- a/FoodOrders/AbstractShopFileImplement/DataFileSingleton.cs +++ b/FoodOrders/AbstractShopFileImplement/DataFileSingleton.cs @@ -8,66 +8,58 @@ using System.Xml.Linq; namespace AbstractFoodOrdersFileImplement { - internal class DataFileSingleton - { - private static DataFileSingleton? instance; - private readonly string ComponentFileName = "Component.xml"; - private readonly string OrderFileName = "Order.xml"; - private readonly string DishFileName = "Dish.xml"; - private readonly string ClientFileName = "Client.xml"; + public class DataFileSingleton + { + private static DataFileSingleton? instance; + private readonly string ComponentFileName = "Component.xml"; + private readonly string OrderFileName = "Order.xml"; + private readonly string DishFileName = "Dish.xml"; + private readonly string ClientFileName = "Client.xml"; private readonly string ImplementerFileName = "Implementer.xml"; private readonly string MessageInfoFileName = "MessageInfo.xml"; public List Components { get; private set; } - public List Orders { get; private set; } - public List Dishes { get; private set; } - public List Clients { get; private set; } + public List Orders { get; private set; } + public List Dishes { get; private set; } + public List Clients { get; private set; } public List Implementers { get; private set; } public List MessageInfos { get; private set; } public static DataFileSingleton GetInstance() - { - if (instance == null) - { - instance = new DataFileSingleton(); - } - return instance; - } - public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); - public void SaveDishes() => SaveData(Dishes, DishFileName, "Dishes", x => x.GetXElement); - public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); - public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); + { + if (instance == null) + { + instance = new DataFileSingleton(); + } + return instance; + } + public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); + public void SaveDishes() => SaveData(Dishes, DishFileName, "Dishes", x => x.GetXElement); + public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement); public void SaveMessageInfos() => SaveData(MessageInfos, MessageInfoFileName, "MessageInfos", x => x.GetXElement); private DataFileSingleton() - { - Components = LoadData(ComponentFileName, "Component", x => - Component.Create(x)!)!; - Dishes = LoadData(DishFileName, "Dish", x => - Dish.Create(x)!)!; - Orders = LoadData(OrderFileName, "Order", x => - Order.Create(x)!)!; - Clients = LoadData(ClientFileName, "Client", x => - Client.Create(x)!)!; + { + Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; + Dishes = LoadData(DishFileName, "Dish", x => Dish.Create(x)!)!; + Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; + Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!; Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!; MessageInfos = LoadData(MessageInfoFileName, "MessageInfo", x => MessageInfo.Create(x)!)!; } - private static List? LoadData(string filename, string xmlNodeName, - Func selectFunction) - { - if (File.Exists(filename)) - { - return - XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList(); - } - return new List(); - } - private static void SaveData(List data, string filename, string - xmlNodeName, Func selectFunction) - { - if (data != null) - { - new XDocument(new XElement(xmlNodeName, - data.Select(selectFunction).ToArray())).Save(filename); - } - } - } + private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) + { + if (File.Exists(filename)) + { + return XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList(); + } + return new List(); + } + private static void SaveData(List data, string filename, string xmlNodeName, Func selectFunction) + { + if (data != null) + { + new XDocument(new XElement(xmlNodeName, data.Select(selectFunction).ToArray())).Save(filename); + } + } + } } diff --git a/FoodOrders/AbstractShopFileImplement/FileImplementationExtension.cs b/FoodOrders/AbstractShopFileImplement/FileImplementationExtension.cs new file mode 100644 index 0000000..c68f658 --- /dev/null +++ b/FoodOrders/AbstractShopFileImplement/FileImplementationExtension.cs @@ -0,0 +1,27 @@ +using AbstractFoodOrdersContracts.DI; +using AbstractFoodOrdersContracts.StoragesContracts; +using AbstractFoodOrdersFileImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersFileImplement +{ + public class FileImplementationExtension : IImplementationExtension + { + public int Priority => 1; + + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/FoodOrders/AbstractShopFileImplement/Implements/BackUpInfo.cs b/FoodOrders/AbstractShopFileImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..fba7496 --- /dev/null +++ b/FoodOrders/AbstractShopFileImplement/Implements/BackUpInfo.cs @@ -0,0 +1,43 @@ +using AbstractFoodOrdersContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersFileImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + private readonly DataFileSingleton source; + private readonly PropertyInfo[] sourceProps; + + public BackUpInfo() + { + source = DataFileSingleton.GetInstance(); + sourceProps = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); + } + + public List? GetList() where T : class, new() + { + return (List?)sourceProps + .FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == typeof(T))? + .GetValue(source); + } + + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + var assembly = typeof(BackUpInfo).Assembly; + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsClass && type.GetInterface(modelInterfaceName) != null) + { + return type; + } + } + return null; + } + } +} diff --git a/FoodOrders/AbstractShopFileImplement/Implements/OrderStorage.cs b/FoodOrders/AbstractShopFileImplement/Implements/OrderStorage.cs index 8acbce6..389db17 100644 --- a/FoodOrders/AbstractShopFileImplement/Implements/OrderStorage.cs +++ b/FoodOrders/AbstractShopFileImplement/Implements/OrderStorage.cs @@ -12,59 +12,61 @@ using System.Threading.Tasks; namespace AbstractFoodOrdersFileImplement.Implements { - public class OrderStorage : IOrderStorage - { - private readonly DataFileSingleton source; + public class OrderStorage : IOrderStorage + { + private readonly DataFileSingleton source; + public OrderStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Orders + .Select(x => AccessDishStorage(x.GetViewModel)) + .ToList(); + } - public OrderStorage() - { - source = DataFileSingleton.GetInstance(); - } - - public List GetFullList() - { - return source.Orders.Select(x => x.GetViewModel) - .Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList(); - } - - public List GetFilteredList(OrderSearchModel model) - { + public List GetFilteredList(OrderSearchModel model) + { if (!model.Id.HasValue || !model.DateFrom.HasValue || !model.DateTo.HasValue || !model.OrderStatus.HasValue) { return new(); } - if (model.OrderStatus.HasValue) - { - return source.Orders.Where(x => x.ImplementerId == model.ImplementerId) - .Select(x => x.GetViewModel) - .Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList(); - } - if (!model.DateFrom.HasValue || !model.DateTo.HasValue) - { - return source.Orders.Where(x => x.Id == model.Id) - .Select(x => x.GetViewModel) - .Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList(); - } - else - { - return source.Orders.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) - .Select(x => x.GetViewModel) - .Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList(); + if (model.OrderStatus.HasValue) + { + return source.Orders + .Where(x => x.ImplementerId == model.ImplementerId) + .Select(x => AccessDishStorage(x.GetViewModel)) + .ToList(); + } + if (!model.DateFrom.HasValue || !model.DateTo.HasValue) + { + return source.Orders + .Where(x => x.Id == model.Id) + .Select(x => AccessDishStorage(x.GetViewModel)) + .ToList(); + } + else + { + return source.Orders + .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) + .Select(x => AccessDishStorage(x.GetViewModel)) + .ToList(); } } - public OrderViewModel? GetElement(OrderSearchModel model) - { + public OrderViewModel? GetElement(OrderSearchModel model) + { if (!model.Id.HasValue && !model.ImplementerId.HasValue && !model.OrderStatus.HasValue) { return null; } - if (!model.Id.HasValue) - { + if (!model.Id.HasValue) + { return AccessDishStorage(source.Orders - .FirstOrDefault(x => model.ImplementerId.HasValue && model.OrderStatus.HasValue - && x.ImplementerId == model.ImplementerId && x.Status == model.OrderStatus) - ?.GetViewModel); + .FirstOrDefault(x => model.ImplementerId.HasValue && model.OrderStatus.HasValue + && x.ImplementerId == model.ImplementerId && x.Status == model.OrderStatus) + ?.GetViewModel); } else { @@ -74,16 +76,8 @@ namespace AbstractFoodOrdersFileImplement.Implements } } - //для загрузки названий изделия в заказе - private OrderViewModel AccessDishStorage(OrderViewModel model) - { - string? dishName = source.Dishes.FirstOrDefault(x => x.Id == model?.DishId)?.DishName; - if (dishName != null) model.DishName = dishName; - return model; - } - - public OrderViewModel? Insert(OrderBindingModel model) - { + public OrderViewModel? Insert(OrderBindingModel model) + { model.Id = source.Orders.Count > 0 ? source.Orders.Max(x => x.Id) + 1 : 1; var newOrder = Order.Create(model); if (newOrder == null) @@ -95,8 +89,8 @@ namespace AbstractFoodOrdersFileImplement.Implements return AccessDishStorage(newOrder.GetViewModel); } - public OrderViewModel? Update(OrderBindingModel model) - { + public OrderViewModel? Update(OrderBindingModel model) + { var order = source.Orders.FirstOrDefault(x => x.Id == model.Id); if (order == null) { @@ -107,8 +101,8 @@ namespace AbstractFoodOrdersFileImplement.Implements return AccessDishStorage(order.GetViewModel); } - public OrderViewModel? Delete(OrderBindingModel model) - { + public OrderViewModel? Delete(OrderBindingModel model) + { var element = source.Orders.FirstOrDefault(x => x.Id == model.Id); if (element != null) { @@ -118,5 +112,12 @@ namespace AbstractFoodOrdersFileImplement.Implements } return null; } - } + + public OrderViewModel AccessDishStorage(OrderViewModel model) + { + string? pastryName = source.Dishes.FirstOrDefault(x => x.Id == model?.DishId)?.DishName; + if (pastryName != null) model.DishName = pastryName; + return model; + } + } } diff --git a/FoodOrders/AbstractShopFileImplement/Models/Client.cs b/FoodOrders/AbstractShopFileImplement/Models/Client.cs index 95a84f0..e643df6 100644 --- a/FoodOrders/AbstractShopFileImplement/Models/Client.cs +++ b/FoodOrders/AbstractShopFileImplement/Models/Client.cs @@ -4,18 +4,24 @@ using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace AbstractFoodOrdersFileImplement.Models { - public class Client:IClientModel + [DataContract] + public class Client:IClientModel { + [DataMember] public int Id { get; set; } - public string ClientFIO { get; set; } = string.Empty; - public string Password { get; set; } = string.Empty; - public string Email { get; set; } = string.Empty; + [DataMember] + public string ClientFIO { get; set; } = string.Empty; + [DataMember] + public string Password { get; set; } = string.Empty; + [DataMember] + public string Email { get; set; } = string.Empty; public static Client? Create(ClientBindingModel? model) { if (model == null) diff --git a/FoodOrders/AbstractShopFileImplement/Models/Component.cs b/FoodOrders/AbstractShopFileImplement/Models/Component.cs index 9a8b444..f0aabea 100644 --- a/FoodOrders/AbstractShopFileImplement/Models/Component.cs +++ b/FoodOrders/AbstractShopFileImplement/Models/Component.cs @@ -1,15 +1,20 @@ using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.ViewModels; using AbstractFoodOrdersDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace AbstractFoodOrdersFileImplement.Models { + [DataContract] public class Component : IComponentModel { - public int Id { get; private set; } - public string ComponentName { get; private set; } = string.Empty; - public double Cost { get; set; } + [DataMember] + public int Id { get; private set; } + [DataMember] + public string ComponentName { get; private set; } = string.Empty; + [DataMember] + public double Cost { get; set; } public static Component? Create(ComponentBindingModel model) { if (model == null) diff --git a/FoodOrders/AbstractShopFileImplement/Models/Dish.cs b/FoodOrders/AbstractShopFileImplement/Models/Dish.cs index 3d65a46..2af4113 100644 --- a/FoodOrders/AbstractShopFileImplement/Models/Dish.cs +++ b/FoodOrders/AbstractShopFileImplement/Models/Dish.cs @@ -4,17 +4,22 @@ using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace AbstractFoodOrdersFileImplement.Models { + [DataContract] public class Dish : IDishModel { - public int Id { get; private set; } - public string DishName { get; private set; } = string.Empty; - public double Price { get; private set; } + [DataMember] + public int Id { get; private set; } + [DataMember] + public string DishName { get; private set; } = string.Empty; + [DataMember] + public double Price { get; private set; } public Dictionary Components { get; private set; } = new(); private Dictionary? _dishComponents = null; diff --git a/FoodOrders/AbstractShopFileImplement/Models/Implementer.cs b/FoodOrders/AbstractShopFileImplement/Models/Implementer.cs index 81efbf4..9f5027b 100644 --- a/FoodOrders/AbstractShopFileImplement/Models/Implementer.cs +++ b/FoodOrders/AbstractShopFileImplement/Models/Implementer.cs @@ -4,21 +4,25 @@ using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace AbstractFoodOrdersFileImplement.Models { + [DataContract] public class Implementer:IImplementerModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string ImplementerFIO { get; set; } = string.Empty; - + [DataMember] public string Password { get; set; } = string.Empty; - + [DataMember] public int WorkExperience { get; set; } - + [DataMember] public int Qualification { get; set; } public static Implementer? Create(ImplementerBindingModel? model) diff --git a/FoodOrders/AbstractShopFileImplement/Models/MessageInfo.cs b/FoodOrders/AbstractShopFileImplement/Models/MessageInfo.cs index 1cf1c5e..d539827 100644 --- a/FoodOrders/AbstractShopFileImplement/Models/MessageInfo.cs +++ b/FoodOrders/AbstractShopFileImplement/Models/MessageInfo.cs @@ -4,20 +4,29 @@ using AbstractFoodOrdersDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace AbstractFoodOrdersFileImplement.Models { + [DataContract] public class MessageInfo:IMessageInfoModel { + [DataMember] public string MessageId { get; set; } = string.Empty; + [DataMember] public int? ClientId { get; set; } + [DataMember] public string SenderName { get; set; } = string.Empty; + [DataMember] public DateTime DateDelivery { get; set; } + [DataMember] public string Subject { get; set; } = string.Empty; + [DataMember] public string Body { get; set; } = string.Empty; + public int Id { get; private set; } public static MessageInfo? Create(MessageInfoBindingModel model) { diff --git a/FoodOrders/AbstractShopFileImplement/Models/Order.cs b/FoodOrders/AbstractShopFileImplement/Models/Order.cs index 22f0e62..7cee613 100644 --- a/FoodOrders/AbstractShopFileImplement/Models/Order.cs +++ b/FoodOrders/AbstractShopFileImplement/Models/Order.cs @@ -6,100 +6,102 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace AbstractFoodOrdersFileImplement.Models { - public class Order : IOrderModel - { - public int Id { get; private set; } - public int DishId { get; private set; } - public int ClientId { get; private set; } + [DataContract] + public class Order : IOrderModel + { + [DataMember] + public int Id { get; private set; } + [DataMember] + public int DishId { get; private set; } + [DataMember] + public int ClientId { get; private set; } + [DataMember] public int? ImplementerId { get; private set; } + [DataMember] public int Count { get; private set; } - public double Sum { get; private set; } - public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; - public DateTime DateCreate { get; private set; } = DateTime.Now; - public DateTime? DateImplement { get; private set; } + [DataMember] + public double Sum { get; private set; } + [DataMember] + public OrderStatus Status { get; private set; } + [DataMember] + public DateTime DateCreate { get; private set; } + [DataMember] + public DateTime? DateImplement { get; private set; } - public static Order? Create(OrderBindingModel? model) - { - if (model == null) - { - return null; - } - return new Order() - { - Id = model.Id, - DishId = model.DishId, - ClientId = model.ClientId, - Count = model.Count, - Sum = model.Sum, - Status = model.Status, - DateCreate = model.DateCreate, - DateImplement = model.DateImplement, - ImplementerId = model.ImplementerId - }; - } - public static Order? Create(XElement element) - { - if (element == null) - { - return null; - } - return new Order() - { - Id = Convert.ToInt32(element.Attribute("Id")!.Value), - DishId = Convert.ToInt32(element.Element("DishId")!.Value), - ClientId = Convert.ToInt32(element.Element("ClientId")!.Value), - Count = Convert.ToInt32(element.Element("Count")!.Value), - Sum = Convert.ToDouble(element.Element("Sum")!.Value), - Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value), - DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value), - DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : - Convert.ToDateTime(element.Element("DateImplement")!.Value), + public static Order? Create(OrderBindingModel? model) + { + if (model == null) + { + return null; + } + return new Order() + { + Id = model.Id, + DishId = model.DishId, + Count = model.Count, + Sum = model.Sum, + Status = model.Status, + DateCreate = model.DateCreate, + DateImplement = model.DateImplement, + ImplementerId = model.ImplementerId + }; + } + public static Order? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Order() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + DishId = Convert.ToInt32(element.Element("DishId")!.Value), + Count = Convert.ToInt32(element.Element("Count")!.Value), + Sum = Convert.ToDouble(element.Element("Sum")!.Value), + Status = (OrderStatus)Convert.ToInt32(element.Element("Status")!.Value), + DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value), + DateImplement = Convert.ToDateTime(String.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : element.Element("DateImplement")!.Value), ImplementerId = Convert.ToInt32(element.Element("ImplementerId")!.Value), }; - } - public void Update(OrderBindingModel? model) - { - if (model == null) - { - return; - } - DishId = model.DishId; - ClientId = model.ClientId; - Count = model.Count; - Sum = model.Sum; - Status = model.Status; - DateCreate = model.DateCreate; - DateImplement = model.DateImplement; - ImplementerId = model.ImplementerId; } - public OrderViewModel GetViewModel => new() - { - Id = Id, - DishId = DishId, - ClientId = ClientId, - Count = Count, - Sum = Sum, - Status = Status, - DateCreate = DateCreate, - DateImplement = DateImplement, + + public void Update(OrderBindingModel model) + { + if (model == null) + { + return; + } + Status = model.Status; + ImplementerId = model.ImplementerId; + if (model.DateImplement.HasValue) DateImplement = model.DateImplement; + } + public OrderViewModel GetViewModel => new() + { + Id = Id, + DishId = DishId, + Count = Count, + Sum = Sum, + Status = Status, + DateCreate = DateCreate, + DateImplement = DateImplement, ImplementerId = ImplementerId }; - public XElement GetXElement => new("Order", - new XAttribute("Id", Id), - new XElement("DishId", DishId), - new XElement("ClientId", ClientId), - new XElement("ImplementerId", ImplementerId.ToString()), - new XElement("Count", Count.ToString()), - new XElement("Sum", Sum.ToString()), - new XElement("Status", Status.ToString()), - new XElement("DateCreate", DateCreate.ToString()), - new XElement("DateImplement", DateImplement.ToString())); - } + public XElement GetXElement => new("Order", + new XAttribute("Id", Id), + new XElement("DishId", DishId), + new XElement("Count", Count.ToString()), + new XElement("Sum", Sum.ToString()), + new XElement("Status", ((int)Status).ToString()), + new XElement("DateCreate", DateCreate.ToString()), + new XElement("ImplementerId", ImplementerId.ToString()), + new XElement("DateImplement", DateImplement.ToString())); + } } diff --git a/FoodOrders/FoodOrders/FormComponents.cs b/FoodOrders/FoodOrders/FormComponents.cs index 4a1577e..31e78d7 100644 --- a/FoodOrders/FoodOrders/FormComponents.cs +++ b/FoodOrders/FoodOrders/FormComponents.cs @@ -1,5 +1,6 @@ using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BusinessLogicsContracts; +using AbstractFoodOrdersContracts.DI; using FoodOrders; using Microsoft.Extensions.Logging; using System; @@ -43,31 +44,24 @@ namespace FoodOrders } private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); - if (service is FormComponent form) - { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } - } - } + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } private void ButtonUpd_Click(object sender, EventArgs e) { - if (dataGridView.SelectedRows.Count == 1) - { - var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); - if (service is FormComponent form) - { - form.Id = - Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } - } - } - } + if (dataGridView.SelectedRows.Count == 1) + { + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } private void ButtonDel_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) diff --git a/FoodOrders/FoodOrders/FormDish.cs b/FoodOrders/FoodOrders/FormDish.cs index c4d583c..37b07bf 100644 --- a/FoodOrders/FoodOrders/FormDish.cs +++ b/FoodOrders/FoodOrders/FormDish.cs @@ -1,5 +1,6 @@ using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BusinessLogicsContracts; +using AbstractFoodOrdersContracts.DI; using AbstractFoodOrdersContracts.SearchModels; using AbstractFoodOrdersDataModels.Models; using Microsoft.Extensions.Logging; @@ -81,9 +82,8 @@ namespace FoodOrders } private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormDishComponent)); - if (service is FormDishComponent form) - { + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { if (form.ComponentModel == null) @@ -103,18 +103,15 @@ namespace FoodOrders } LoadData(); } - } + } private void ButtonUpd_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) { - var service = - Program.ServiceProvider?.GetService(typeof(FormDishComponent)); - if (service is FormDishComponent form) - { - int id = - Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); + var form = DependencyManager.Instance.Resolve(); + + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); form.Id = id; form.Count = _productComponents[id].Item2; if (form.ShowDialog() == DialogResult.OK) @@ -127,7 +124,7 @@ namespace FoodOrders _productComponents[form.Id] = (form.ComponentModel, form.Count); LoadData(); } - } + } } private void ButtonDel_Click(object sender, EventArgs e) diff --git a/FoodOrders/FoodOrders/FormDishes.cs b/FoodOrders/FoodOrders/FormDishes.cs index 50c050a..4b8a5b7 100644 --- a/FoodOrders/FoodOrders/FormDishes.cs +++ b/FoodOrders/FoodOrders/FormDishes.cs @@ -1,5 +1,6 @@ using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BusinessLogicsContracts; +using AbstractFoodOrdersContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -46,31 +47,25 @@ namespace FoodOrders private void buttonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormDish)); - if (service is FormDish form) - { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } - } - } + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } private void buttonUpd_Click(object sender, EventArgs e) { - if (dataGridView.SelectedRows.Count == 1) - { - var service = Program.ServiceProvider?.GetService(typeof(FormDish)); - if (service is FormDish form) - { - form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } - } - } - } + if (dataGridView.SelectedRows.Count == 1) + { + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } private void buttonDel_Click(object sender, EventArgs e) { diff --git a/FoodOrders/FoodOrders/FormImplementers.cs b/FoodOrders/FoodOrders/FormImplementers.cs index d3ee27b..8b4edd5 100644 --- a/FoodOrders/FoodOrders/FormImplementers.cs +++ b/FoodOrders/FoodOrders/FormImplementers.cs @@ -1,5 +1,6 @@ using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BusinessLogicsContracts; +using AbstractFoodOrdersContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -45,13 +46,10 @@ namespace FoodOrders private void buttonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormCreateImplementer)); - if (service is FormCreateImplementer form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } + LoadData(); } } @@ -59,14 +57,11 @@ namespace FoodOrders { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormCreateImplementer)); - if (service is FormCreateImplementer form) + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) { - form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } + LoadData(); } } } diff --git a/FoodOrders/FoodOrders/FormMain.Designer.cs b/FoodOrders/FoodOrders/FormMain.Designer.cs index 8a2c169..5cc2b2c 100644 --- a/FoodOrders/FoodOrders/FormMain.Designer.cs +++ b/FoodOrders/FoodOrders/FormMain.Designer.cs @@ -34,6 +34,7 @@ БлюдаToolStripMenuItem = new ToolStripMenuItem(); ClientToolStripMenuItem = new ToolStripMenuItem(); исполнителиToolStripMenuItem = new ToolStripMenuItem(); + письмаToolStripMenuItem = new ToolStripMenuItem(); отчётыToolStripMenuItem = new ToolStripMenuItem(); ComponentToolStripMenuItem = new ToolStripMenuItem(); ComponentProductsToolStripMenuItem = new ToolStripMenuItem(); @@ -43,7 +44,7 @@ ButtonCreateOrder = new Button(); ButtonIssuedOrder = new Button(); ButtonRef = new Button(); - письмаToolStripMenuItem = new ToolStripMenuItem(); + создатьБекапToolStripMenuItem = new ToolStripMenuItem(); menuStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); @@ -51,7 +52,7 @@ // menuStrip // menuStrip.ImageScalingSize = new Size(20, 20); - menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem, запускРаботыToolStripMenuItem }); + menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem, запускРаботыToolStripMenuItem, создатьБекапToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; menuStrip.Size = new Size(1104, 28); @@ -68,31 +69,38 @@ // КомпонентыToolStripMenuItem // КомпонентыToolStripMenuItem.Name = "КомпонентыToolStripMenuItem"; - КомпонентыToolStripMenuItem.Size = new Size(224, 26); + КомпонентыToolStripMenuItem.Size = new Size(185, 26); КомпонентыToolStripMenuItem.Text = "Компоненты"; КомпонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click; // // БлюдаToolStripMenuItem // БлюдаToolStripMenuItem.Name = "БлюдаToolStripMenuItem"; - БлюдаToolStripMenuItem.Size = new Size(224, 26); + БлюдаToolStripMenuItem.Size = new Size(185, 26); БлюдаToolStripMenuItem.Text = "Блюда"; БлюдаToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click; // // ClientToolStripMenuItem // ClientToolStripMenuItem.Name = "ClientToolStripMenuItem"; - ClientToolStripMenuItem.Size = new Size(224, 26); + ClientToolStripMenuItem.Size = new Size(185, 26); ClientToolStripMenuItem.Text = "Клиенты"; ClientToolStripMenuItem.Click += ClientToolStripMenuItem_Click; // // исполнителиToolStripMenuItem // исполнителиToolStripMenuItem.Name = "исполнителиToolStripMenuItem"; - исполнителиToolStripMenuItem.Size = new Size(224, 26); + исполнителиToolStripMenuItem.Size = new Size(185, 26); исполнителиToolStripMenuItem.Text = "Исполнители"; исполнителиToolStripMenuItem.Click += ИсполнителиToolStripMenuItem_Click; // + // письмаToolStripMenuItem + // + письмаToolStripMenuItem.Name = "письмаToolStripMenuItem"; + письмаToolStripMenuItem.Size = new Size(185, 26); + письмаToolStripMenuItem.Text = "Письма"; + письмаToolStripMenuItem.Click += письмаToolStripMenuItem_Click; + // // отчётыToolStripMenuItem // отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ComponentToolStripMenuItem, ComponentProductsToolStripMenuItem, OrdersToolStripMenuItem }); @@ -169,12 +177,12 @@ ButtonRef.UseVisualStyleBackColor = true; ButtonRef.Click += ButtonRef_Click; // - // письмаToolStripMenuItem + // создатьБекапToolStripMenuItem // - письмаToolStripMenuItem.Name = "письмаToolStripMenuItem"; - письмаToolStripMenuItem.Size = new Size(224, 26); - письмаToolStripMenuItem.Text = "Письма"; - письмаToolStripMenuItem.Click += письмаToolStripMenuItem_Click; + создатьБекапToolStripMenuItem.Name = "создатьБекапToolStripMenuItem"; + создатьБекапToolStripMenuItem.Size = new Size(123, 24); + создатьБекапToolStripMenuItem.Text = "Создать Бекап"; + создатьБекапToolStripMenuItem.Click += создатьБекапToolStripMenuItem_Click; // // FormMain // @@ -215,5 +223,6 @@ private ToolStripMenuItem запускРаботыToolStripMenuItem; private ToolStripMenuItem исполнителиToolStripMenuItem; private ToolStripMenuItem письмаToolStripMenuItem; + private ToolStripMenuItem создатьБекапToolStripMenuItem; } } \ No newline at end of file diff --git a/FoodOrders/FoodOrders/FormMain.cs b/FoodOrders/FoodOrders/FormMain.cs index c97a32d..eae6bef 100644 --- a/FoodOrders/FoodOrders/FormMain.cs +++ b/FoodOrders/FoodOrders/FormMain.cs @@ -1,6 +1,7 @@ using AbstractFoodOrdersBusinessLogic.BusinessLogics; using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BusinessLogicsContracts; +using AbstractFoodOrdersContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -20,13 +21,15 @@ namespace FoodOrders private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; private readonly IWorkProcess _workProcess; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) + private readonly IBackUpLogic _backUpLogic; + public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess, IBackUpLogic backUpLogic) { InitializeComponent(); _logger = logger; _orderLogic = orderLogic; _reportLogic = reportLogic; _workProcess = workProcess; + _backUpLogic = backUpLogic; } private void FormMain_Load(object sender, EventArgs e) { @@ -34,7 +37,7 @@ namespace FoodOrders } private void LoadData() { - + try { dataGridView.FillAndConfigGrid(_orderLogic.ReadList(null)); @@ -48,75 +51,19 @@ namespace FoodOrders } private void КомпонентыToolStripMenuItem_Click(object sender, EventArgs e) { - var service = - Program.ServiceProvider?.GetService(typeof(FormComponents)); - if (service is FormComponents form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void ИзделияToolStripMenuItem_Click(object sender, EventArgs e) { - var service = - Program.ServiceProvider?.GetService(typeof(FormDishes)); - if (service is FormDishes form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void ButtonCreateOrder_Click(object sender, EventArgs e) { - var service = - Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); - if (service is FormCreateOrder form) - { - form.ShowDialog(); - LoadData(); - } - } - private void ButtonTakeOrderInWork_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id); - try - { - var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка передачи заказа в работу"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - private void ButtonOrderReady_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); - try - { - var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id }); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка отметки о готовности заказа"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); + LoadData(); } private void ButtonIssuedOrder_Click(object sender, EventArgs e) { @@ -167,52 +114,61 @@ namespace FoodOrders private void ComponentProductsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportDishComponents)); - if (service is FormReportDishComponents form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void OrdersToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders)); - if (service is FormReportOrders form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void ClientToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormClients)); - if (service is FormClients form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void ИсполнителиToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementers)); - if (service is FormImplementers form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void ЗапускРаботыToolStripMenuItem_Click(object sender, EventArgs e) { - _workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic); - MessageBox.Show("Процесс обработки запущен", "Сообщение", - MessageBoxButtons.OK, MessageBoxIcon.Information); + _workProcess.DoWork(DependencyManager.Instance.Resolve(), _orderLogic); + MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void письмаToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormMails)); - if (service is FormMails form) + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); + } + + private void создатьБекапToolStripMenuItem_Click(object sender, EventArgs e) + { + try { - form.ShowDialog(); + if (_backUpLogic != null) + { + var fbd = new FolderBrowserDialog(); + if (fbd.ShowDialog() == DialogResult.OK) + { + _backUpLogic.CreateBackUp(new BackUpSaveBinidngModel + { + FolderName = fbd.SelectedPath + }); + MessageBox.Show("Бекап создан", "Сообщение", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); } } } diff --git a/FoodOrders/FoodOrders/Program.cs b/FoodOrders/FoodOrders/Program.cs index eafe1f5..addd959 100644 --- a/FoodOrders/FoodOrders/Program.cs +++ b/FoodOrders/FoodOrders/Program.cs @@ -10,6 +10,7 @@ using NLog.Extensions.Logging; using System.Drawing; using AbstractFoodOrdersBusinessLogic.MailWorker; using AbstractFoodOrdersContracts.BindingModels; +using AbstractFoodOrdersContracts.DI; namespace FoodOrders { @@ -26,83 +27,71 @@ namespace FoodOrders // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - var services = new ServiceCollection(); - ConfigureServices(services); - _serviceProvider = services.BuildServiceProvider(); + InitDependency(); + try { - var mailSender = - _serviceProvider.GetService(); + var mailSender = DependencyManager.Instance.Resolve(); mailSender?.MailConfig(new MailConfigBindingModel { - MailLogin = - System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty, - MailPassword = - System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty, - SmtpClientHost = - System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty, - SmtpClientPort = - Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]), - PopHost = - System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty, - PopPort = - Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"]) + MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty, + MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty, + SmtpClientHost = System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty, + SmtpClientPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]), + PopHost = System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty, + PopPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"]) }); - // - var timer = new System.Threading.Timer(new - TimerCallback(MailCheck!), null, 0, 10000); + + var timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 100000); } catch (Exception ex) { - var logger = _serviceProvider.GetService(); + var logger = DependencyManager.Instance.Resolve(); logger?.LogError(ex, " "); } - Application.Run(_serviceProvider.GetRequiredService()); - } - private static void ConfigureServices(ServiceCollection services) - { - services.AddLogging(option => - { - option.SetMinimumLevel(LogLevel.Information); - option.AddNLog("nlog.config"); - }); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddSingleton(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + Application.Run(DependencyManager.Instance.Resolve()); } - private static void MailCheck(object obj) => ServiceProvider?.GetService()?.MailCheck(); + private static void InitDependency() + { + DependencyManager.InitDependency(); + + DependencyManager.Instance.AddLogging(option => + { + option.SetMinimumLevel(LogLevel.Information); + option.AddNLog("nlog.config"); + }); + + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(true); + DependencyManager.Instance.RegisterType(); + + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + private static void MailCheck(object obj) => DependencyManager.Instance.Resolve()?.MailCheck(); } } \ No newline at end of file diff --git a/FoodOrders/ImplementationExtensions/AbstractFoodOrdersContracts.dll b/FoodOrders/ImplementationExtensions/AbstractFoodOrdersContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..3c905b39fdd887aeb51fdd6914a5a590fad93804 GIT binary patch literal 31744 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 literal 0 HcmV?d00001 diff --git a/FoodOrders/ImplementationExtensions/AbstractFoodOrdersListImplement.dll b/FoodOrders/ImplementationExtensions/AbstractFoodOrdersListImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..8a25078b8a7219bcb4240f997010f216ef421802 GIT binary patch literal 26112 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 Date: Thu, 1 Jun 2023 16:28:18 +0400 Subject: [PATCH 4/6] =?UTF-8?q?=D0=9B=D0=B0=D0=B18=20-=20=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D1=811.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/BackUpInfo.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 FoodOrders/AbstractFoodOrdersListImplement/Implements/BackUpInfo.cs diff --git a/FoodOrders/AbstractFoodOrdersListImplement/Implements/BackUpInfo.cs b/FoodOrders/AbstractFoodOrdersListImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..fd7d11f --- /dev/null +++ b/FoodOrders/AbstractFoodOrdersListImplement/Implements/BackUpInfo.cs @@ -0,0 +1,22 @@ +using AbstractFoodOrdersContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractFoodOrdersListImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + throw new NotImplementedException(); + } + + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + throw new NotImplementedException(); + } + } +} -- 2.25.1 From 35f9ccddd248f30e7152ad3725fdeb6288b6cb11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=A5=D0=B0=D1=80=D0=BB?= =?UTF-8?q?=D0=B0=D0=BC=D0=BE=D0=B2?= Date: Sat, 3 Jun 2023 16:42:08 +0400 Subject: [PATCH 5/6] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=BB=D0=B0=D0=B1=D0=B0=E2=84=968?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/BackUpLogic.cs | 9 +++------ .../AbstractFoodOrdersDatabaseImplement.dll | Bin 0 -> 88064 bytes 2 files changed, 3 insertions(+), 6 deletions(-) create mode 100644 FoodOrders/ImplementationExtensions/AbstractFoodOrdersDatabaseImplement.dll diff --git a/FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs b/FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs index b6a3906..ed332a3 100644 --- a/FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs +++ b/FoodOrders/AbstractFoodOrdersBusinessLogic/BusinessLogics/BackUpLogic.cs @@ -57,8 +57,7 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics nameof(assembly)); } var types = assembly.GetTypes(); - var method = GetType().GetMethod("SaveToFile", - BindingFlags.NonPublic | BindingFlags.Instance); + var method = GetType().GetMethod("SaveToFile", BindingFlags.NonPublic | BindingFlags.Instance); _logger.LogDebug("Find {count} types", types.Length); foreach (var type in types) { @@ -73,8 +72,7 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics } _logger.LogDebug("Call SaveToFile method for {name} type", type.Name); // вызываем метод на выполнение - method?.MakeGenericMethod(modelType).Invoke(this, new - object[] { model.FolderName }); + method?.MakeGenericMethod(modelType).Invoke(this, new object[] { model.FolderName }); } } _logger.LogDebug("Create zip and remove folder"); @@ -97,8 +95,7 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics return; } var jsonFormatter = new DataContractJsonSerializer(typeof(List)); - using var fs = new FileStream(string.Format("{0}/{1}.json", - folderName, typeof(T).Name), FileMode.OpenOrCreate); + using var fs = new FileStream(string.Format("{0}/{1}.json", folderName, typeof(T).Name), FileMode.OpenOrCreate); jsonFormatter.WriteObject(fs, records); } } diff --git a/FoodOrders/ImplementationExtensions/AbstractFoodOrdersDatabaseImplement.dll b/FoodOrders/ImplementationExtensions/AbstractFoodOrdersDatabaseImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..2180ceef41a3723c6a19e8d35f4e64278b494eb0 GIT binary patch literal 88064 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 O$j^F1f8M@E8u&j%PQ73N literal 0 HcmV?d00001 -- 2.25.1 From 6a1082424b6e18792faec3ead98f426789ef23c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=A5=D0=B0=D1=80=D0=BB?= =?UTF-8?q?=D0=B0=D0=BC=D0=BE=D0=B2?= Date: Sat, 3 Jun 2023 16:55:39 +0400 Subject: [PATCH 6/6] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81#8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/MessageInfoStorage.cs | 2 +- .../AbstractFoodOrdersListImplement/Models/MessageInfo.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs b/FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs index 956e02f..eb84506 100644 --- a/FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs +++ b/FoodOrders/AbstractFoodOrdersListImplement/Implements/MessageInfoStorage.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; namespace AbstractFoodOrdersListImplement.Implements { - public class MessageInfoStorage:IMessageInfoStorage + public class MessageInfoStorage : IMessageInfoStorage { private readonly DataListSingleton _source; diff --git a/FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs b/FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs index ac8ef4e..48b49c9 100644 --- a/FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs +++ b/FoodOrders/AbstractFoodOrdersListImplement/Models/MessageInfo.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace AbstractFoodOrdersListImplement.Models { - public class MessageInfo:IMessageInfoModel + public class MessageInfo : IMessageInfoModel { public string MessageId { get; set; } = string.Empty; public int? ClientId { get; set; } -- 2.25.1