From 619f61d5bc5ff1420239632f53e546d398f9e0fc Mon Sep 17 00:00:00 2001 From: Kamil Haliullov Date: Fri, 26 May 2023 00:19:35 +0400 Subject: [PATCH] lab8 --- .../FlowerShop/DataGridViewExtension.cs | 50 ++++++++ FlowerShop/FlowerShop/FlowerShop.csproj | 2 +- FlowerShop/FlowerShop/FormBouquet.cs | 79 +++++++------ FlowerShop/FlowerShop/FormBouquets.cs | 34 ++---- FlowerShop/FlowerShop/FormClients.cs | 8 +- FlowerShop/FlowerShop/FormComponents.cs | 32 ++---- FlowerShop/FlowerShop/FormImplementers.cs | 32 ++---- FlowerShop/FlowerShop/FormMails.cs | 12 +- FlowerShop/FlowerShop/FormMain.Designer.cs | 32 ++++-- FlowerShop/FlowerShop/FormMain.cs | 101 ++++++++--------- FlowerShop/FlowerShop/Program.cs | 82 ++++++-------- .../BusinessLogics/BackUpLogics.cs | 107 ++++++++++++++++++ .../Attributes/ColumnAttribute.cs | 20 ++++ .../Attributes/GridViewAutoSize.cs | 14 +++ .../BindingModels/BackUpSaveBindingModel.cs | 7 ++ .../BindingModels/MessageInfoBindingModel.cs | 2 + .../BusinessLogicsContracts/IBackUpLogic.cs | 9 ++ .../DI/DependencyManager.cs | 39 +++++++ .../DI/IDependencyContainer.cs | 15 +++ .../DI/IImplementationExtension.cs | 9 ++ .../DI/ServiceDependencyContainer.cs | 60 ++++++++++ .../DI/ServiceProviderLoader.cs | 48 ++++++++ .../DI/UnityDependencyContainer.cs | 38 +++++++ .../FlowerShopContracts.csproj | 6 + .../StoragesContracts/IBackUpInfo.cs | 8 ++ .../ViewModels/BouquetViewModel.cs | 10 +- .../ViewModels/ClientViewModel.cs | 11 +- .../ViewModels/ComponentViewModel.cs | 9 +- .../ViewModels/ImplementerViewModel.cs | 13 ++- .../ViewModels/MessageInfoViewModel.cs | 17 +-- .../ViewModels/OrderViewModel.cs | 26 +++-- .../Models/IMessageInfoModel.cs | 2 +- .../DatabaseImplementationExtension.cs | 22 ++++ .../FlowerShopDatabaseImplement.csproj | 4 + .../Implements/BackUpInfo.cs | 30 +++++ ...ner.cs => 20230510065624_init.Designer.cs} | 4 +- ...510060536_db.cs => 20230510065624_init.cs} | 2 +- .../Models/Bouquet.cs | 6 + .../Models/Client.cs | 6 + .../Models/Component.cs | 6 +- .../Models/Implementer.cs | 7 ++ .../Models/MessageInfo.cs | 10 ++ .../Models/Order.cs | 11 ++ .../FileImplementationExtension.cs | 22 ++++ .../FlowerShopFileImplement.csproj | 4 + .../Implements/BackUpInfo.cs | 32 ++++++ .../FlowerShopFileImplement/Models/Bouquet.cs | 9 +- .../FlowerShopFileImplement/Models/Client.cs | 8 ++ .../Models/Component.cs | 6 +- .../Models/Implementer.cs | 12 +- .../Models/MessageInfo.cs | 10 ++ .../FlowerShopFileImplement/Models/Order.cs | 15 ++- .../FlowerShopListImplement.csproj | 4 + .../Implements/BackUpInfo.cs | 17 +++ .../ListImplementationExtension.cs | 22 ++++ .../Models/MessageInfo.cs | 2 + .../FlowerShopContracts.dll | Bin 0 -> 31744 bytes .../FlowerShopDataModels.dll | Bin 0 -> 6656 bytes .../FlowerShopDatabaseImplement.dll | Bin 0 -> 83968 bytes .../FlowerShopFileImplement.dll | Bin 0 -> 40960 bytes .../FlowerShopListImplement.dll | Bin 0 -> 26112 bytes 61 files changed, 919 insertions(+), 286 deletions(-) create mode 100644 FlowerShop/FlowerShop/DataGridViewExtension.cs create mode 100644 FlowerShop/FlowerShopBusinessLogic/BusinessLogics/BackUpLogics.cs create mode 100644 FlowerShop/FlowerShopContracts/Attributes/ColumnAttribute.cs create mode 100644 FlowerShop/FlowerShopContracts/Attributes/GridViewAutoSize.cs create mode 100644 FlowerShop/FlowerShopContracts/BindingModels/BackUpSaveBindingModel.cs create mode 100644 FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 FlowerShop/FlowerShopContracts/DI/DependencyManager.cs create mode 100644 FlowerShop/FlowerShopContracts/DI/IDependencyContainer.cs create mode 100644 FlowerShop/FlowerShopContracts/DI/IImplementationExtension.cs create mode 100644 FlowerShop/FlowerShopContracts/DI/ServiceDependencyContainer.cs create mode 100644 FlowerShop/FlowerShopContracts/DI/ServiceProviderLoader.cs create mode 100644 FlowerShop/FlowerShopContracts/DI/UnityDependencyContainer.cs create mode 100644 FlowerShop/FlowerShopContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 FlowerShop/FlowerShopDatabaseImplement/DatabaseImplementationExtension.cs create mode 100644 FlowerShop/FlowerShopDatabaseImplement/Implements/BackUpInfo.cs rename FlowerShop/FlowerShopDatabaseImplement/Migrations/{20230510060536_db.Designer.cs => 20230510065624_init.Designer.cs} (99%) rename FlowerShop/FlowerShopDatabaseImplement/Migrations/{20230510060536_db.cs => 20230510065624_init.cs} (90%) create mode 100644 FlowerShop/FlowerShopFileImplement/FileImplementationExtension.cs create mode 100644 FlowerShop/FlowerShopFileImplement/Implements/BackUpInfo.cs create mode 100644 FlowerShop/FlowerShopListImplement/Implements/BackUpInfo.cs create mode 100644 FlowerShop/FlowerShopListImplement/ListImplementationExtension.cs create mode 100644 FlowerShop/ImplementationExtensions/FlowerShopContracts.dll create mode 100644 FlowerShop/ImplementationExtensions/FlowerShopDataModels.dll create mode 100644 FlowerShop/ImplementationExtensions/FlowerShopDatabaseImplement.dll create mode 100644 FlowerShop/ImplementationExtensions/FlowerShopFileImplement.dll create mode 100644 FlowerShop/ImplementationExtensions/FlowerShopListImplement.dll diff --git a/FlowerShop/FlowerShop/DataGridViewExtension.cs b/FlowerShop/FlowerShop/DataGridViewExtension.cs new file mode 100644 index 0000000..b5c06cc --- /dev/null +++ b/FlowerShop/FlowerShop/DataGridViewExtension.cs @@ -0,0 +1,50 @@ +using FlowerShopContracts.Attributes; + +namespace FlowerShop +{ + 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/FlowerShop/FlowerShop/FlowerShop.csproj b/FlowerShop/FlowerShop/FlowerShop.csproj index a2de8e0..724db71 100644 --- a/FlowerShop/FlowerShop/FlowerShop.csproj +++ b/FlowerShop/FlowerShop/FlowerShop.csproj @@ -22,7 +22,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/FlowerShop/FlowerShop/FormBouquet.cs b/FlowerShop/FlowerShop/FormBouquet.cs index 199e887..e846c48 100644 --- a/FlowerShop/FlowerShop/FormBouquet.cs +++ b/FlowerShop/FlowerShop/FormBouquet.cs @@ -1,5 +1,6 @@ using FlowerShopContracts.BindingModels; using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.DI; using FlowerShopContracts.SearchModels; using FlowerShopDataModels.Models; using Microsoft.Extensions.Logging; @@ -70,9 +71,42 @@ namespace FlowerShop private void buttonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormBouquetComponent)); - if (service is FormBouquetComponent form) + var form = DependencyManager.Instance.Resolve(); + + if (form.ShowDialog() == DialogResult.OK) { + if (form.ComponentModel == null) + { + return; + } + + _logger.LogInformation("Добавление нового компонента: { ComponentName} - { Count}", form.ComponentModel.ComponentName, form.Count); + + if (_bouquetComponents.ContainsKey(form.Id)) + { + _bouquetComponents[form.Id] = (form.ComponentModel, form.Count); + } + + else + { + _bouquetComponents.Add(form.Id, (form.ComponentModel, form.Count)); + } + + LoadData(); + } + } + + private void buttonChange_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + var form = DependencyManager.Instance.Resolve(); + + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); + + form.Id = id; + form.Count = _bouquetComponents[id].Item2; + if (form.ShowDialog() == DialogResult.OK) { if (form.ComponentModel == null) @@ -80,51 +114,14 @@ namespace FlowerShop return; } - _logger.LogInformation("Добавление нового компонента: { ComponentName} - { Count}", form.ComponentModel.ComponentName, form.Count); - - if (_bouquetComponents.ContainsKey(form.Id)) - { - _bouquetComponents[form.Id] = (form.ComponentModel, form.Count); - } - - else - { - _bouquetComponents.Add(form.Id, (form.ComponentModel, form.Count)); - } - + _logger.LogInformation("Изменение компонента: { ComponentName} - { Count}", form.ComponentModel.ComponentName, form.Count); + _bouquetComponents[form.Id] = (form.ComponentModel, form.Count); LoadData(); } } } - private void buttonChange_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - var service = Program.ServiceProvider?.GetService(typeof(FormBouquetComponent)); - if (service is FormBouquetComponent form) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); - form.Id = id; - form.Count = _bouquetComponents[id].Item2; - - if (form.ShowDialog() == DialogResult.OK) - { - if (form.ComponentModel == null) - { - return; - } - - _logger.LogInformation("Изменение компонента: { ComponentName} - { Count}", form.ComponentModel.ComponentName, form.Count); - _bouquetComponents[form.Id] = (form.ComponentModel, form.Count); - LoadData(); - } - } - } - - } - private void buttonDelete_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) diff --git a/FlowerShop/FlowerShop/FormBouquets.cs b/FlowerShop/FlowerShop/FormBouquets.cs index 2dca392..7a9d999 100644 --- a/FlowerShop/FlowerShop/FormBouquets.cs +++ b/FlowerShop/FlowerShop/FormBouquets.cs @@ -1,5 +1,6 @@ using FlowerShopContracts.BindingModels; using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.DI; using Microsoft.Extensions.Logging; namespace FlowerShop @@ -20,18 +21,9 @@ namespace FlowerShop { try { - var list = _logic.ReadList(null); - - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["BouquetName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["BouquetComponents"].Visible = false; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Receiving bouquets"); - } catch (Exception ex) { @@ -42,14 +34,11 @@ namespace FlowerShop private void AddButton_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormBouquet)); + var form = DependencyManager.Instance.Resolve(); - if (service is FormBouquet form) + if (form.ShowDialog() == DialogResult.OK) { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } + LoadData(); } } @@ -57,16 +46,13 @@ namespace FlowerShop { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormBouquet)); + var form = DependencyManager.Instance.Resolve(); - if (service is FormBouquet form) + 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/FlowerShop/FlowerShop/FormClients.cs b/FlowerShop/FlowerShop/FormClients.cs index 24b70c7..0907b82 100644 --- a/FlowerShop/FlowerShop/FormClients.cs +++ b/FlowerShop/FlowerShop/FormClients.cs @@ -25,13 +25,7 @@ namespace FlowerShop { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Receiving clients"); } diff --git a/FlowerShop/FlowerShop/FormComponents.cs b/FlowerShop/FlowerShop/FormComponents.cs index 1bfbe37..3724795 100644 --- a/FlowerShop/FlowerShop/FormComponents.cs +++ b/FlowerShop/FlowerShop/FormComponents.cs @@ -1,5 +1,6 @@ using FlowerShopContracts.BindingModels; using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.DI; using Microsoft.Extensions.Logging; namespace FlowerShop @@ -25,13 +26,8 @@ namespace FlowerShop { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Receiving components"); } catch (Exception ex) @@ -43,13 +39,11 @@ namespace FlowerShop private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); - if (service is FormComponent form) + var form = DependencyManager.Instance.Resolve(); + + if (form.ShowDialog() == DialogResult.OK) { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } + LoadData(); } } @@ -57,14 +51,12 @@ namespace FlowerShop { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); - if (service is FormComponent 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/FlowerShop/FlowerShop/FormImplementers.cs b/FlowerShop/FlowerShop/FormImplementers.cs index e8d5f44..d7b6e2e 100644 --- a/FlowerShop/FlowerShop/FormImplementers.cs +++ b/FlowerShop/FlowerShop/FormImplementers.cs @@ -1,5 +1,6 @@ using FlowerShopContracts.BindingModels; using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.DI; using Microsoft.Extensions.Logging; namespace FlowerShop @@ -25,13 +26,7 @@ namespace FlowerShop { 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("Загрузка исполнителей"); } @@ -44,13 +39,11 @@ namespace FlowerShop private void buttonCreate_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); - if (service is FormImplementer form) + var form = DependencyManager.Instance.Resolve(); + + if (form.ShowDialog() == DialogResult.OK) { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } + LoadData(); } } @@ -58,14 +51,13 @@ namespace FlowerShop { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); - if (service is FormImplementer 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/FlowerShop/FlowerShop/FormMails.cs b/FlowerShop/FlowerShop/FormMails.cs index b8fc97b..59d03c4 100644 --- a/FlowerShop/FlowerShop/FormMails.cs +++ b/FlowerShop/FlowerShop/FormMails.cs @@ -19,17 +19,9 @@ namespace FlowerShop { try { - var list = _logic.ReadList(null); + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["MessageId"].Visible = false; - dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } - - _logger.LogInformation("Loading mails"); + _logger.LogInformation("Loading mails"); } catch (Exception ex) { diff --git a/FlowerShop/FlowerShop/FormMain.Designer.cs b/FlowerShop/FlowerShop/FormMain.Designer.cs index 2ef7b9f..0ad415b 100644 --- a/FlowerShop/FlowerShop/FormMain.Designer.cs +++ b/FlowerShop/FlowerShop/FormMain.Designer.cs @@ -38,12 +38,13 @@ this.bouquetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.clientsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.implementersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.mailsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.reportsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.listOfBouquetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.componentsByBouquetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.listOfOrdersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.doWorksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.mailsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.createBackupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.menuStrip.SuspendLayout(); this.SuspendLayout(); @@ -98,7 +99,8 @@ this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.guidesToolStripMenuItem, this.reportsToolStripMenuItem, - this.doWorksToolStripMenuItem}); + this.doWorksToolStripMenuItem, + this.createBackupToolStripMenuItem}); this.menuStrip.Location = new System.Drawing.Point(0, 0); this.menuStrip.Name = "menuStrip"; this.menuStrip.Padding = new System.Windows.Forms.Padding(4, 1, 0, 1); @@ -121,31 +123,38 @@ // componentsToolStripMenuItem // this.componentsToolStripMenuItem.Name = "componentsToolStripMenuItem"; - this.componentsToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.componentsToolStripMenuItem.Size = new System.Drawing.Size(149, 22); this.componentsToolStripMenuItem.Text = "Компоненты"; this.componentsToolStripMenuItem.Click += new System.EventHandler(this.componentsToolStripMenuItem_Click); // // bouquetsToolStripMenuItem // this.bouquetsToolStripMenuItem.Name = "bouquetsToolStripMenuItem"; - this.bouquetsToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.bouquetsToolStripMenuItem.Size = new System.Drawing.Size(149, 22); this.bouquetsToolStripMenuItem.Text = "Букеты"; this.bouquetsToolStripMenuItem.Click += new System.EventHandler(this.bouquetsToolStripMenuItem_Click); // // clientsToolStripMenuItem // this.clientsToolStripMenuItem.Name = "clientsToolStripMenuItem"; - this.clientsToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.clientsToolStripMenuItem.Size = new System.Drawing.Size(149, 22); this.clientsToolStripMenuItem.Text = "Клиенты"; this.clientsToolStripMenuItem.Click += new System.EventHandler(this.clientsToolStripMenuItem_Click); // // implementersToolStripMenuItem // this.implementersToolStripMenuItem.Name = "implementersToolStripMenuItem"; - this.implementersToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.implementersToolStripMenuItem.Size = new System.Drawing.Size(149, 22); this.implementersToolStripMenuItem.Text = "Исполнители"; this.implementersToolStripMenuItem.Click += new System.EventHandler(this.implementersToolStripMenuItem_Click); // + // mailsToolStripMenuItem + // + this.mailsToolStripMenuItem.Name = "mailsToolStripMenuItem"; + this.mailsToolStripMenuItem.Size = new System.Drawing.Size(149, 22); + this.mailsToolStripMenuItem.Text = "Письма"; + this.mailsToolStripMenuItem.Click += new System.EventHandler(this.mailsToolStripMenuItem_Click); + // // reportsToolStripMenuItem // this.reportsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -184,12 +193,12 @@ this.doWorksToolStripMenuItem.Text = "Запуск работ"; this.doWorksToolStripMenuItem.Click += new System.EventHandler(this.doWorksToolStripMenuItem_Click); // - // mailsToolStripMenuItem + // createBackupToolStripMenuItem // - this.mailsToolStripMenuItem.Name = "mailsToolStripMenuItem"; - this.mailsToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - this.mailsToolStripMenuItem.Text = "Письма"; - this.mailsToolStripMenuItem.Click += new System.EventHandler(this.mailsToolStripMenuItem_Click); + this.createBackupToolStripMenuItem.Name = "createBackupToolStripMenuItem"; + this.createBackupToolStripMenuItem.Size = new System.Drawing.Size(97, 22); + this.createBackupToolStripMenuItem.Text = "Создать бэкап"; + this.createBackupToolStripMenuItem.Click += new System.EventHandler(this.createBackupToolStripMenuItem_Click); // // FormMain // @@ -232,5 +241,6 @@ private ToolStripMenuItem implementersToolStripMenuItem; private ToolStripMenuItem doWorksToolStripMenuItem; private ToolStripMenuItem mailsToolStripMenuItem; + private ToolStripMenuItem createBackupToolStripMenuItem; } } \ No newline at end of file diff --git a/FlowerShop/FlowerShop/FormMain.cs b/FlowerShop/FlowerShop/FormMain.cs index 58667d8..9859bb9 100644 --- a/FlowerShop/FlowerShop/FormMain.cs +++ b/FlowerShop/FlowerShop/FormMain.cs @@ -1,6 +1,6 @@ -using FlowerShopBusinessLogic.BusinessLogics; -using FlowerShopContracts.BindingModels; +using FlowerShopContracts.BindingModels; using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.DI; using Microsoft.Extensions.Logging; namespace FlowerShop @@ -11,14 +11,16 @@ namespace FlowerShop private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; private readonly IWorkProcess _workProcess; + private readonly IBackUpLogic _backUpLogic; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) + 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 MainForm_Load(object sender, EventArgs e) @@ -31,15 +33,7 @@ namespace FlowerShop _logger.LogInformation("Загрузка заказов"); try { - var list = _orderLogic.ReadList(null); - - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["BouquetId"].Visible = false; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["ImplementerId"].Visible = false; - } + dataGridView.FillAndConfigGrid(_orderLogic.ReadList(null)); } catch (Exception ex) { @@ -50,31 +44,22 @@ namespace FlowerShop private void componentsToolStripMenuItem_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 bouquetsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormBouquets)); - - if (service is FormBouquets form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void buttonCreate_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); - if (service is FormCreateOrder form) - { - form.ShowDialog(); - LoadData(); - } + var form = DependencyManager.Instance.Resolve(); + + form.ShowDialog(); + LoadData(); } private void buttonToWork_Click(object sender, EventArgs e) @@ -173,52 +158,62 @@ namespace FlowerShop private void componentsByBouquetsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportBouquetComponents)); - if (service is FormReportBouquetComponents form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void listOfOrdersToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportOrder)); - if (service is FormReportOrder form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void clientsToolStripMenuItem_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 doWorksToolStripMenuItem_Click(object sender, EventArgs e) { - _workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic); + _workProcess.DoWork(DependencyManager.Instance.Resolve(), _orderLogic); + MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void implementersToolStripMenuItem_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 mailsToolStripMenuItem_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 createBackupToolStripMenuItem_Click(object sender, EventArgs e) + { + try { - form.ShowDialog(); + if (_backUpLogic != null) + { + var fbd = new FolderBrowserDialog(); + if (fbd.ShowDialog() == DialogResult.OK) + { + _backUpLogic.CreateBackUp(new BackUpSaveBindingModel + { + FolderName = fbd.SelectedPath + }); + + MessageBox.Show("Бекап создан", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } diff --git a/FlowerShop/FlowerShop/Program.cs b/FlowerShop/FlowerShop/Program.cs index c829707..96f7bbd 100644 --- a/FlowerShop/FlowerShop/Program.cs +++ b/FlowerShop/FlowerShop/Program.cs @@ -1,33 +1,26 @@ -using FlowerShopContracts.StoragesContracts; using FlowerShopBusinessLogic.OfficePackage; using FlowerShopBusinessLogic.OfficePackage.Implements; -using Microsoft.Extensions.DependencyInjection; -using FlowerShopDatabaseImplement.Implements; using FlowerShopBusinessLogic.BusinessLogics; using FlowerShopContracts.BusinessLogicsContracts; using NLog.Extensions.Logging; using Microsoft.Extensions.Logging; using FlowerShopBusinessLogic.MailWorker; using FlowerShopContracts.BindingModels; +using FlowerShopContracts.DI; namespace FlowerShop { internal static class Program { - private static ServiceProvider? _serviceProvider; - public static ServiceProvider? ServiceProvider => _serviceProvider; - [STAThread] static void Main() { 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, @@ -42,57 +35,54 @@ namespace FlowerShop } catch (Exception ex) { - var logger = _serviceProvider.GetService(); + var logger = DependencyManager.Instance.Resolve(); logger?.LogError(ex, "Error during work with mail"); } - Application.Run(_serviceProvider.GetRequiredService()); + Application.Run(DependencyManager.Instance.Resolve()); } - private static void MailCheck(object obj) => ServiceProvider?.GetService()?.MailCheck(); + private static void MailCheck(object obj) => DependencyManager.Instance.Resolve()?.MailCheck(); - private static void ConfigureServices(ServiceCollection services) + private static void InitDependency() { - services.AddLogging(option => + DependencyManager.InitDependency(); + + DependencyManager.Instance.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(); + 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(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); - services.AddSingleton(); + DependencyManager.Instance.RegisterType(true); - 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(); + 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(); } } } \ No newline at end of file diff --git a/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/BackUpLogics.cs b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/BackUpLogics.cs new file mode 100644 index 0000000..7012d4e --- /dev/null +++ b/FlowerShop/FlowerShopBusinessLogic/BusinessLogics/BackUpLogics.cs @@ -0,0 +1,107 @@ +using FlowerShopContracts.BusinessLogicsContracts; +using FlowerShopContracts.StoragesContracts; +using FlowerShopContracts.BindingModels; +using FlowerShopDataModels; +using Microsoft.Extensions.Logging; +using System.IO.Compression; +using System.Reflection; +using System.Runtime.Serialization.Json; + +namespace FlowerShopBusinessLogic.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(BackUpSaveBindingModel 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/FlowerShop/FlowerShopContracts/Attributes/ColumnAttribute.cs b/FlowerShop/FlowerShopContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..f0b08d4 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,20 @@ +namespace FlowerShopContracts.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/FlowerShop/FlowerShopContracts/Attributes/GridViewAutoSize.cs b/FlowerShop/FlowerShopContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..1735943 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,14 @@ +namespace FlowerShopContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + None = 1, + ColumnHeader = 2, + AllCellsExceptHeader = 4, + AllCells = 6, + DisplayedCellsExceptHeader = 8, + DisplayedCells = 10, + Fill = 16 + } +} diff --git a/FlowerShop/FlowerShopContracts/BindingModels/BackUpSaveBindingModel.cs b/FlowerShop/FlowerShopContracts/BindingModels/BackUpSaveBindingModel.cs new file mode 100644 index 0000000..42017a2 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/BindingModels/BackUpSaveBindingModel.cs @@ -0,0 +1,7 @@ +namespace FlowerShopContracts.BindingModels +{ + public class BackUpSaveBindingModel + { + public string FolderName { get; set; } = string.Empty; + } +} diff --git a/FlowerShop/FlowerShopContracts/BindingModels/MessageInfoBindingModel.cs b/FlowerShop/FlowerShopContracts/BindingModels/MessageInfoBindingModel.cs index 17b59d5..4195d52 100644 --- a/FlowerShop/FlowerShopContracts/BindingModels/MessageInfoBindingModel.cs +++ b/FlowerShop/FlowerShopContracts/BindingModels/MessageInfoBindingModel.cs @@ -15,5 +15,7 @@ namespace FlowerShopContracts.BindingModels public string Subject { get; set; } = string.Empty; public string Body { get; set; } = string.Empty; + + public int Id => throw new NotImplementedException(); } } diff --git a/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IBackUpLogic.cs b/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..5667b61 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,9 @@ +using FlowerShopContracts.BindingModels; + +namespace FlowerShopContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBindingModel model); + } +} diff --git a/FlowerShop/FlowerShopContracts/DI/DependencyManager.cs b/FlowerShop/FlowerShopContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..152f8f0 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/DI/DependencyManager.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Logging; + +namespace FlowerShopContracts.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/FlowerShop/FlowerShopContracts/DI/IDependencyContainer.cs b/FlowerShop/FlowerShopContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..9846189 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/DI/IDependencyContainer.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.Logging; + +namespace FlowerShopContracts.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/FlowerShop/FlowerShopContracts/DI/IImplementationExtension.cs b/FlowerShop/FlowerShopContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..ae598e9 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/DI/IImplementationExtension.cs @@ -0,0 +1,9 @@ +namespace FlowerShopContracts.DI +{ + public interface IImplementationExtension + { + public int Priority { get; } + + public void RegisterServices(); + } +} diff --git a/FlowerShop/FlowerShopContracts/DI/ServiceDependencyContainer.cs b/FlowerShop/FlowerShopContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..56cfc56 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/DI/ServiceDependencyContainer.cs @@ -0,0 +1,60 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; + +namespace FlowerShopContracts.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/FlowerShop/FlowerShopContracts/DI/ServiceProviderLoader.cs b/FlowerShop/FlowerShopContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..4f10a40 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,48 @@ +using System.Reflection; + +namespace FlowerShopContracts.DI +{ + public class ServiceProviderLoader + { + 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/FlowerShop/FlowerShopContracts/DI/UnityDependencyContainer.cs b/FlowerShop/FlowerShopContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..4b1c338 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Logging; +using Unity.Microsoft.Logging; +using Unity; + +namespace FlowerShopContracts.DI +{ + public class UnityDependencyContainer : IDependencyContainer + { + private readonly IUnityContainer _container; + + public UnityDependencyContainer() + { + _container = new UnityContainer(); + } + + public void AddLogging(Action configure) + { + var factory = LoggerFactory.Create(configure); + _container.AddExtension(new LoggingExtension(factory)); + } + + public void RegisterType(bool isSingle) where T : class + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + + } + + public T Resolve() + { + return _container.Resolve(); + } + + void IDependencyContainer.RegisterType(bool isSingle) + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + } + } +} diff --git a/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj b/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj index 5192185..fac472e 100644 --- a/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj +++ b/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj @@ -6,6 +6,12 @@ enable + + + + + + diff --git a/FlowerShop/FlowerShopContracts/StoragesContracts/IBackUpInfo.cs b/FlowerShop/FlowerShopContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..1fd9af5 --- /dev/null +++ b/FlowerShop/FlowerShopContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,8 @@ +namespace FlowerShopContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} diff --git a/FlowerShop/FlowerShopContracts/ViewModels/BouquetViewModel.cs b/FlowerShop/FlowerShopContracts/ViewModels/BouquetViewModel.cs index 2a7d6ed..f2d6d34 100644 --- a/FlowerShop/FlowerShopContracts/ViewModels/BouquetViewModel.cs +++ b/FlowerShop/FlowerShopContracts/ViewModels/BouquetViewModel.cs @@ -1,15 +1,17 @@ -using FlowerShopDataModels.Models; -using System.ComponentModel; +using FlowerShopContracts.Attributes; +using FlowerShopDataModels.Models; namespace FlowerShopContracts.ViewModels { public class BouquetViewModel : IBouquetModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Название букета")] + [Column("Название букета", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string BouquetName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column("Цена", width: 150)] public double Price { get; set; } + [Column(visible: false)] public Dictionary BouquetComponents { get; set; } = new(); } } diff --git a/FlowerShop/FlowerShopContracts/ViewModels/ClientViewModel.cs b/FlowerShop/FlowerShopContracts/ViewModels/ClientViewModel.cs index 55e7336..a1f7c88 100644 --- a/FlowerShop/FlowerShopContracts/ViewModels/ClientViewModel.cs +++ b/FlowerShop/FlowerShopContracts/ViewModels/ClientViewModel.cs @@ -1,19 +1,20 @@ -using FlowerShopDataModels.Models; -using System.ComponentModel; +using FlowerShopContracts.Attributes; +using FlowerShopDataModels.Models; namespace FlowerShopContracts.ViewModels { public class ClientViewModel : IClientModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО клиента")] + [Column("ФИО клиента", width: 150)] public string ClientFIO { get; set; } = string.Empty; - [DisplayName("Логин (почта)")] + [Column("Логин (почта)", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Email { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column("Пароль", width: 150)] public string Password { get; set; } = string.Empty; } } diff --git a/FlowerShop/FlowerShopContracts/ViewModels/ComponentViewModel.cs b/FlowerShop/FlowerShopContracts/ViewModels/ComponentViewModel.cs index 3a06a8f..70dc98c 100644 --- a/FlowerShop/FlowerShopContracts/ViewModels/ComponentViewModel.cs +++ b/FlowerShop/FlowerShopContracts/ViewModels/ComponentViewModel.cs @@ -1,14 +1,15 @@ -using FlowerShopDataModels.Models; -using System.ComponentModel; +using FlowerShopContracts.Attributes; +using FlowerShopDataModels.Models; namespace FlowerShopContracts.ViewModels { public class ComponentViewModel : IComponentModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Название компонента")] + [Column("Название компонента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ComponentName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column("Цена", width: 100)] public double Cost { get; set; } } } diff --git a/FlowerShop/FlowerShopContracts/ViewModels/ImplementerViewModel.cs b/FlowerShop/FlowerShopContracts/ViewModels/ImplementerViewModel.cs index ef2e876..8f3e573 100644 --- a/FlowerShop/FlowerShopContracts/ViewModels/ImplementerViewModel.cs +++ b/FlowerShop/FlowerShopContracts/ViewModels/ImplementerViewModel.cs @@ -1,22 +1,23 @@ -using FlowerShopDataModels.Models; -using System.ComponentModel; +using FlowerShopContracts.Attributes; +using FlowerShopDataModels.Models; namespace FlowerShopContracts.ViewModels { public class ImplementerViewModel : IImplementerModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО")] + [Column("ФИО", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column("Пароль", width: 200)] public string Password { get; set; } = string.Empty; - [DisplayName("Трудовой стаж")] + [Column("Трудовой стаж", width: 200)] public int WorkExperience { get; set; } - [DisplayName("Квалификация")] + [Column("Квалификация", width: 200)] public int Qualification { get; set; } } } diff --git a/FlowerShop/FlowerShopContracts/ViewModels/MessageInfoViewModel.cs b/FlowerShop/FlowerShopContracts/ViewModels/MessageInfoViewModel.cs index 07a4dc7..8462e46 100644 --- a/FlowerShop/FlowerShopContracts/ViewModels/MessageInfoViewModel.cs +++ b/FlowerShop/FlowerShopContracts/ViewModels/MessageInfoViewModel.cs @@ -1,20 +1,23 @@ -using FlowerShopDataModels.Models; -using System.ComponentModel; +using FlowerShopContracts.Attributes; +using FlowerShopDataModels.Models; namespace FlowerShopContracts.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("Отправитель", gridViewAutoSize: GridViewAutoSize.DisplayedCells, isUseAutoSize: true)] public string SenderName { get; set; } = string.Empty; - [DisplayName("Дата письма")] + [Column("Дата письма", width: 100)] public DateTime DateDelivery { get; set; } - [DisplayName("Заголовок")] + [Column("Заголовок", width: 150)] public string Subject { get; set; } = string.Empty; - [DisplayName("Текст")] + [Column("Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Body { get; set; } = string.Empty; + [Column(visible: false)] + public int Id => throw new NotImplementedException(); } } diff --git a/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs b/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs index 27abdd1..a066f39 100644 --- a/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs +++ b/FlowerShop/FlowerShopContracts/ViewModels/OrderViewModel.cs @@ -1,34 +1,36 @@ -using FlowerShopDataModels.Enums; +using FlowerShopContracts.Attributes; +using FlowerShopDataModels.Enums; using FlowerShopDataModels.Models; -using System.ComponentModel; namespace FlowerShopContracts.ViewModels { public class OrderViewModel : IOrderModel { - [DisplayName("Номер")] + [Column("Номер", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int Id { get; set; } + [Column(visible: false)] public int BouquetId { get; set; } - + [Column(visible: false)] public int ClientId { get; set; } - [DisplayName("ФИО клиента")] + [Column("ФИО клиента", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string ClientFIO { get; set; } = string.Empty; + [Column(visible: false)] public int? ImplementerId { get; set; } - [DisplayName("ФИО исполнителя")] + [Column("ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Букет")] + [Column("Букет", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string BouquetName { get; set; } = string.Empty; - [DisplayName("Количество")] + [Column("Количество", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int Count { get; set; } - [DisplayName("Сумма")] + [Column("Сумма", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public double Sum { get; set; } - [DisplayName("Статус")] + [Column("Статус", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; - [DisplayName("Дата создания")] + [Column("Дата создания", width: 100)] public DateTime DateCreate { get; set; } = DateTime.Now; - [DisplayName("Дата выполнения")] + [Column("Дата выполнения", width: 100)] public DateTime? DateImplement { get; set; } } } diff --git a/FlowerShop/FlowerShopDataModels/Models/IMessageInfoModel.cs b/FlowerShop/FlowerShopDataModels/Models/IMessageInfoModel.cs index 1c244fe..1decfd2 100644 --- a/FlowerShop/FlowerShopDataModels/Models/IMessageInfoModel.cs +++ b/FlowerShop/FlowerShopDataModels/Models/IMessageInfoModel.cs @@ -1,6 +1,6 @@ namespace FlowerShopDataModels.Models { - public interface IMessageInfoModel + public interface IMessageInfoModel : IId { string MessageId { get; } int? ClientId { get; } diff --git a/FlowerShop/FlowerShopDatabaseImplement/DatabaseImplementationExtension.cs b/FlowerShop/FlowerShopDatabaseImplement/DatabaseImplementationExtension.cs new file mode 100644 index 0000000..36f0665 --- /dev/null +++ b/FlowerShop/FlowerShopDatabaseImplement/DatabaseImplementationExtension.cs @@ -0,0 +1,22 @@ +using FlowerShopContracts.DI; +using FlowerShopContracts.StoragesContracts; +using FlowerShopDatabaseImplement.Implements; + +namespace FlowerShopDatabaseImplement +{ + 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/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj index 81edb67..1b8f1a9 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj +++ b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj @@ -24,4 +24,8 @@ + + + + diff --git a/FlowerShop/FlowerShopDatabaseImplement/Implements/BackUpInfo.cs b/FlowerShop/FlowerShopDatabaseImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..b97c07d --- /dev/null +++ b/FlowerShop/FlowerShopDatabaseImplement/Implements/BackUpInfo.cs @@ -0,0 +1,30 @@ +using FlowerShopContracts.StoragesContracts; + +namespace FlowerShopDatabaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new FlowerShopDatabase(); + + 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/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510060536_db.Designer.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510065624_init.Designer.cs similarity index 99% rename from FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510060536_db.Designer.cs rename to FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510065624_init.Designer.cs index fc2c1c7..730f6ee 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510060536_db.Designer.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510065624_init.Designer.cs @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace FlowerShopDatabaseImplement.Migrations { [DbContext(typeof(FlowerShopDatabase))] - [Migration("20230510060536_db")] - partial class db + [Migration("20230510065624_init")] + partial class init { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510060536_db.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510065624_init.cs similarity index 90% rename from FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510060536_db.cs rename to FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510065624_init.cs index 0fc7c2b..76aac14 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510060536_db.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20230510065624_init.cs @@ -5,7 +5,7 @@ namespace FlowerShopDatabaseImplement.Migrations { /// - public partial class db : Migration + public partial class init : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/Bouquet.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/Bouquet.cs index 0cb5b5e..98cf5d6 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Models/Bouquet.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/Bouquet.cs @@ -3,22 +3,28 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Runtime.Serialization; namespace FlowerShopDatabaseImplement.Models { + [DataContract] public class Bouquet : IBouquetModel { + [DataMember] public int Id { get; private set; } [Required] + [DataMember] public string BouquetName { get; private set; } = string.Empty; [Required] + [DataMember] public double Price { get; private set; } private Dictionary? _bouquetComponents = null; [NotMapped] + [DataMember] public Dictionary BouquetComponents { get diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/Client.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/Client.cs index 367405c..3e7e405 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Models/Client.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/Client.cs @@ -3,20 +3,26 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace FlowerShopDatabaseImplement.Models { + [DataContract] public class Client : IClientModel { + [DataMember] public int Id { get; private set; } [Required] + [DataMember] public string ClientFIO { get; private set; } = string.Empty; [Required] + [DataMember] public string Email { get; private set; } = string.Empty; [Required] + [DataMember] public string Password { get; private set; } = string.Empty; [ForeignKey("ClientId")] diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/Component.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/Component.cs index 117df09..db3dffe 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Models/Component.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/Component.cs @@ -3,18 +3,22 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; - +using System.Runtime.Serialization; namespace FlowerShopDatabaseImplement.Models { + [DataContract] public class Component : IComponentModel { + [DataMember] public int Id { get; private set; } [Required] + [DataMember] public string ComponentName { get; private set; } = String.Empty; [Required] + [DataMember] public double Cost { get; set; } [ForeignKey("ComponentId")] diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/Implementer.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/Implementer.cs index 8543d47..11f8454 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Models/Implementer.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/Implementer.cs @@ -2,19 +2,26 @@ using FlowerShopContracts.BindingModels; using FlowerShopContracts.ViewModels; using System.ComponentModel.DataAnnotations.Schema; +using System.Runtime.Serialization; namespace FlowerShopDatabaseImplement.Models { + [DataContract] public class Implementer : IImplementerModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string ImplementerFIO { get; private set; } = string.Empty; + [DataMember] public string Password { get; private set; } = string.Empty; + [DataMember] public int WorkExperience { get; private set; } + [DataMember] public int Qualification { get; private set; } [ForeignKey("ImplementerId")] diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/MessageInfo.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/MessageInfo.cs index 492729c..8424d41 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Models/MessageInfo.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/MessageInfo.cs @@ -2,22 +2,30 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace FlowerShopDatabaseImplement.Models { + [DataContract] public class MessageInfo : IMessageInfoModel { [Key] + [DataMember] public string MessageId { get; private set; } = string.Empty; + [DataMember] public int? ClientId { get; private set; } + [DataMember] public string SenderName { get; private set; } = string.Empty; + [DataMember] public DateTime DateDelivery { get; private set; } = DateTime.Now; + [DataMember] public string Subject { get; private set; } = string.Empty; + [DataMember] public string Body { get; private set; } = string.Empty; public virtual Client? Client { get; private set; } @@ -49,5 +57,7 @@ namespace FlowerShopDatabaseImplement.Models SenderName = SenderName, DateDelivery = DateDelivery, }; + + public int Id => throw new NotImplementedException(); } } diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs index 1c2e136..eb4ca45 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/Order.cs @@ -3,34 +3,45 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Enums; using FlowerShopDataModels.Models; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace FlowerShopDatabaseImplement.Models { + [DataContract] public class Order : IOrderModel { + [DataMember] public int Id { get; private set; } [Required] + [DataMember] public int BouquetId { get; private set; } [Required] + [DataMember] public int ClientId { get; private set; } + [DataMember] public int? ImplementerId { get; private set; } [Required] + [DataMember] public int Count { get; private set; } [Required] + [DataMember] public double Sum { get; private set; } [Required] + [DataMember] public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; [Required] + [DataMember] public DateTime DateCreate { get; private set; } = DateTime.Now; + [DataMember] public DateTime? DateImplement { get; private set; } public virtual Bouquet Bouquet { get; set; } diff --git a/FlowerShop/FlowerShopFileImplement/FileImplementationExtension.cs b/FlowerShop/FlowerShopFileImplement/FileImplementationExtension.cs new file mode 100644 index 0000000..af42a04 --- /dev/null +++ b/FlowerShop/FlowerShopFileImplement/FileImplementationExtension.cs @@ -0,0 +1,22 @@ +using FlowerShopContracts.DI; +using FlowerShopContracts.StoragesContracts; +using FlowerShopFileImplement.Implements; + +namespace FlowerShopFileImplement +{ + 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/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj b/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj index ca6fa62..7bf356e 100644 --- a/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj +++ b/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/FlowerShop/FlowerShopFileImplement/Implements/BackUpInfo.cs b/FlowerShop/FlowerShopFileImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..f0b6d55 --- /dev/null +++ b/FlowerShop/FlowerShopFileImplement/Implements/BackUpInfo.cs @@ -0,0 +1,32 @@ +using FlowerShopContracts.StoragesContracts; + +namespace FlowerShopFileImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + var source = DataFileSingleton.GetInstance(); + + return (List?)source.GetType().GetProperties() + .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/FlowerShop/FlowerShopFileImplement/Models/Bouquet.cs b/FlowerShop/FlowerShopFileImplement/Models/Bouquet.cs index 45f5ceb..d6c8c97 100644 --- a/FlowerShop/FlowerShopFileImplement/Models/Bouquet.cs +++ b/FlowerShop/FlowerShopFileImplement/Models/Bouquet.cs @@ -2,22 +2,27 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.Xml.Linq; -using System.Linq; +using System.Runtime.Serialization; namespace FlowerShopFileImplement.Models { + [DataContract] public class Bouquet : IBouquetModel { + [DataMember] public string BouquetName { get; private set; } = string.Empty; + [DataMember] public double Price { get; private set; } + [DataMember] public int Id { get; private set; } - + public Dictionary Components { get; private set; } = new(); private Dictionary? _bouquetComponents = new(); + [DataMember] public Dictionary BouquetComponents { get diff --git a/FlowerShop/FlowerShopFileImplement/Models/Client.cs b/FlowerShop/FlowerShopFileImplement/Models/Client.cs index 7033563..10a7eec 100644 --- a/FlowerShop/FlowerShopFileImplement/Models/Client.cs +++ b/FlowerShop/FlowerShopFileImplement/Models/Client.cs @@ -2,17 +2,25 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.Xml.Linq; +using System.Runtime.Serialization; + namespace FlowerShopFileImplement.Models { + [DataContract] + public class Client : IClientModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string ClientFIO { get; private set; } = string.Empty; + [DataMember] public string Email { get; private set; } = string.Empty; + [DataMember] public string Password { get; private set; } = string.Empty; public static Client? Create(ClientBindingModel model) diff --git a/FlowerShop/FlowerShopFileImplement/Models/Component.cs b/FlowerShop/FlowerShopFileImplement/Models/Component.cs index cc65f26..80afaf0 100644 --- a/FlowerShop/FlowerShopFileImplement/Models/Component.cs +++ b/FlowerShop/FlowerShopFileImplement/Models/Component.cs @@ -2,16 +2,20 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.Xml.Linq; -using System.Linq; +using System.Runtime.Serialization; namespace FlowerShopFileImplement.Models { + [DataContract] public class Component : IComponentModel { + [DataMember] public string ComponentName { get; private set; } = String.Empty; + [DataMember] public double Cost { get; set; } + [DataMember] public int Id { get; private set; } public static Component? Create(ComponentBindingModel? model) diff --git a/FlowerShop/FlowerShopFileImplement/Models/Implementer.cs b/FlowerShop/FlowerShopFileImplement/Models/Implementer.cs index 706023a..ad02560 100644 --- a/FlowerShop/FlowerShopFileImplement/Models/Implementer.cs +++ b/FlowerShop/FlowerShopFileImplement/Models/Implementer.cs @@ -1,25 +1,27 @@ using FlowerShopContracts.BindingModels; using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Xml.Linq; +using System.Runtime.Serialization; namespace FlowerShopFileImplement.Models { + [DataContract] public class Implementer : IImplementerModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string ImplementerFIO { get; private set; } = string.Empty; + [DataMember] public string Password { get; private set; } = string.Empty; + [DataMember] public int WorkExperience { get; private set; } + [DataMember] public int Qualification { get; private set; } public static Implementer? Create(XElement element) diff --git a/FlowerShop/FlowerShopFileImplement/Models/MessageInfo.cs b/FlowerShop/FlowerShopFileImplement/Models/MessageInfo.cs index 8cca586..10aaf3b 100644 --- a/FlowerShop/FlowerShopFileImplement/Models/MessageInfo.cs +++ b/FlowerShop/FlowerShopFileImplement/Models/MessageInfo.cs @@ -2,21 +2,29 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Models; using System.Xml.Linq; +using System.Runtime.Serialization; namespace FlowerShopFileImplement.Models { + [DataContract] public class MessageInfo : IMessageInfoModel { + [DataMember] public string MessageId { get; private set; } = string.Empty; + [DataMember] public int? ClientId { get; private set; } + [DataMember] public string SenderName { get; private set; } = string.Empty; + [DataMember] public DateTime DateDelivery { get; private set; } = DateTime.Now; + [DataMember] public string Subject { get; private set; } = string.Empty; + [DataMember] public string Body { get; private set; } = string.Empty; public static MessageInfo? Create(MessageInfoBindingModel model) @@ -73,5 +81,7 @@ namespace FlowerShopFileImplement.Models new XAttribute("SenderName", SenderName), new XAttribute("DateDelivery", DateDelivery) ); + + public int Id => throw new NotImplementedException(); } } diff --git a/FlowerShop/FlowerShopFileImplement/Models/Order.cs b/FlowerShop/FlowerShopFileImplement/Models/Order.cs index 5d31587..2d0bc8c 100644 --- a/FlowerShop/FlowerShopFileImplement/Models/Order.cs +++ b/FlowerShop/FlowerShopFileImplement/Models/Order.cs @@ -2,30 +2,41 @@ using FlowerShopContracts.ViewModels; using FlowerShopDataModels.Enums; using FlowerShopDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace FlowerShopFileImplement.Models { + [DataContract] public class Order : IOrderModel { + [DataMember] + public int Id { get; private set; } + + [DataMember] public int BouquetId { get; private set; } + [DataMember] public int ClientId { get; set; } + [DataMember] public int? ImplementerId { get; set; } + [DataMember] public int Count { get; private set; } + [DataMember] public double Sum { get; private set; } + [DataMember] public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; + [DataMember] public DateTime DateCreate { get; private set; } = DateTime.Now; + [DataMember] public DateTime? DateImplement { get; private set; } - public int Id { get; private set; } - public static Order? Create(OrderBindingModel? model) { if (model == null) diff --git a/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj b/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj index ca6fa62..7bf356e 100644 --- a/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj +++ b/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/FlowerShop/FlowerShopListImplement/Implements/BackUpInfo.cs b/FlowerShop/FlowerShopListImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..0c49327 --- /dev/null +++ b/FlowerShop/FlowerShopListImplement/Implements/BackUpInfo.cs @@ -0,0 +1,17 @@ +using FlowerShopContracts.StoragesContracts; + +namespace FlowerShopListImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + throw new NotImplementedException(); + } + + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + throw new NotImplementedException(); + } + } +} diff --git a/FlowerShop/FlowerShopListImplement/ListImplementationExtension.cs b/FlowerShop/FlowerShopListImplement/ListImplementationExtension.cs new file mode 100644 index 0000000..ae9457e --- /dev/null +++ b/FlowerShop/FlowerShopListImplement/ListImplementationExtension.cs @@ -0,0 +1,22 @@ +using FlowerShopContracts.DI; +using FlowerShopContracts.StoragesContracts; +using FlowerShopListImplement.Implements; + +namespace FlowerShopListImplement +{ + 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/FlowerShop/FlowerShopListImplement/Models/MessageInfo.cs b/FlowerShop/FlowerShopListImplement/Models/MessageInfo.cs index 6a8df7e..5977495 100644 --- a/FlowerShop/FlowerShopListImplement/Models/MessageInfo.cs +++ b/FlowerShop/FlowerShopListImplement/Models/MessageInfo.cs @@ -45,5 +45,7 @@ namespace FlowerShopListImplement.Models SenderName = SenderName, DateDelivery = DateDelivery, }; + + public int Id => throw new NotImplementedException(); } } diff --git a/FlowerShop/ImplementationExtensions/FlowerShopContracts.dll b/FlowerShop/ImplementationExtensions/FlowerShopContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..e52a11a19a9d6c860da74618356e1b8daf6234e2 GIT binary patch literal 31744 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 D1CgK# literal 0 HcmV?d00001 diff --git a/FlowerShop/ImplementationExtensions/FlowerShopDataModels.dll b/FlowerShop/ImplementationExtensions/FlowerShopDataModels.dll new file mode 100644 index 0000000000000000000000000000000000000000..ab379bbe1a12f9f5ad0441c6a016bd0ff08b449d GIT binary patch literal 6656 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 IKfnt73raSND*ylh literal 0 HcmV?d00001 diff --git a/FlowerShop/ImplementationExtensions/FlowerShopDatabaseImplement.dll b/FlowerShop/ImplementationExtensions/FlowerShopDatabaseImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..dda8f5bda29e63581e42ba3d687e9a466705469b GIT binary patch literal 83968 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

TD@$xu871HM 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 z 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