From 7f84e760cfee2f3ea98ab96cac52c165ed21966d Mon Sep 17 00:00:00 2001 From: dimazhelovanov Date: Mon, 24 Apr 2023 09:04:20 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataGridViewExtension.cs | 56 +++++++++ .../BlacksmithWorkshop/FormClients.cs | 29 ++--- .../BlacksmithWorkshop/FormComponents.cs | 73 +++++------ .../BlacksmithWorkshop/FormImplementers.cs | 41 ++---- .../BlacksmithWorkshop/FormMails.cs | 17 +-- .../BlacksmithWorkshop/FormMain.Designer.cs | 23 ++-- .../BlacksmithWorkshop/FormMain.cs | 119 ++++++++++-------- .../BlacksmithWorkshop/FormManufacture.cs | 12 +- .../BlacksmithWorkshop/FormManufactures.cs | 69 +++++----- .../BlacksmithWorkshop/Program.cs | 94 +++++++------- .../BusinessLogics/BackUpLogic.cs | 105 ++++++++++++++++ .../Attributes/ColumnAttribute.cs | 27 ++++ .../Attributes/GridViewAutoSize.cs | 20 +++ .../BindingModels/BackUpSaveBinidngModel.cs | 14 +++ .../BindingModels/MessageInfoBindingModel.cs | 2 + .../BlacksmithWorkshopContracts.csproj | 3 + .../BusinessLogicsContracts/IBackUpLogic.cs | 14 +++ .../DI/DependencyManager.cs | 66 ++++++++++ .../DI/IDependencyContainer.cs | 38 ++++++ .../DI/IImplementationExtension.cs | 22 ++++ .../DI/ServiceDependencyContainer.cs | 62 +++++++++ .../DI/ServiceProviderLoader.cs | 67 ++++++++++ .../DI/UnityDependencyContainer.cs | 43 +++++++ .../StoragesContracts/IBackUpInfo.cs | 14 +++ .../ViewModels/ClientViewModel.cs | 23 ++-- .../ViewModels/ComponentViewModel.cs | 12 +- .../ViewModels/ImplementerViewModel.cs | 12 +- .../ViewModels/ManufactureViewModel.cs | 17 +-- .../ViewModels/MessageInfoViewModel.cs | 16 ++- .../ViewModels/OrderViewModel.cs | 41 +++--- .../Models/IMessageInfoModel.cs | 2 +- ...BlacksmithWorkshopDatabaseImplement.csproj | 4 + .../DatabaseImplementationExtension.cs | 32 +++++ .../Implements/BackUpInfo.cs | 32 +++++ .../Implements/ComponentStorage.cs | 4 +- .../Models/Client.cs | 6 + .../Models/Component.cs | 20 +-- .../Models/Implementer.cs | 8 +- .../Models/Manufacture.cs | 17 ++- .../Models/MessageInfo.cs | 15 ++- .../Models/Order.cs | 23 ++-- .../BlacksmithWorkshopFileImplement.csproj | 4 + .../FileImplementationExtension.cs | 33 +++++ .../Implements/BackUpInfo.cs | 34 +++++ .../Models/Client.cs | 9 +- .../Models/Component.cs | 14 ++- .../Models/Implementer.cs | 11 +- .../Models/Manufacture.cs | 14 ++- .../Models/MessageInfo.cs | 15 ++- .../Models/Order.cs | 29 +++-- .../BlacksmithWorkshopListImplement.csproj | 4 + .../Implements/BackUpInfo.cs | 22 ++++ .../ListImplementationExtension.cs | 32 +++++ .../Models/MessageInfo.cs | 2 + .../BlacksmithWorkshopContracts.dll | Bin 0 -> 31744 bytes .../BlacksmithWorkshopDataModel.dll | Bin 0 -> 6144 bytes .../BlacksmithWorkshopDatabaseImplement.dll | Bin 0 -> 75776 bytes .../BlacksmithWorkshopFileImplement.dll | Bin 0 -> 39936 bytes .../BlacksmithWorkshopListImplement.dll | Bin 0 -> 25088 bytes 59 files changed, 1167 insertions(+), 370 deletions(-) create mode 100644 BlacksmithWorkshop/BlacksmithWorkshop/DataGridViewExtension.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogics/BackUpLogic.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/ColumnAttribute.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/GridViewAutoSize.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/BackUpSaveBinidngModel.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/DependencyManager.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IDependencyContainer.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IImplementationExtension.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/ServiceDependencyContainer.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/ServiceProviderLoader.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/UnityDependencyContainer.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/DatabaseImplementationExtension.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/BackUpInfo.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopFileImplement/FileImplementationExtension.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Implements/BackUpInfo.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopListImplement/Implements/BackUpInfo.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopListImplement/ListImplementationExtension.cs create mode 100644 BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopContracts.dll create mode 100644 BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopDataModel.dll create mode 100644 BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopDatabaseImplement.dll create mode 100644 BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopFileImplement.dll create mode 100644 BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopListImplement.dll diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/DataGridViewExtension.cs b/BlacksmithWorkshop/BlacksmithWorkshop/DataGridViewExtension.cs new file mode 100644 index 0000000..82d62ec --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshop/DataGridViewExtension.cs @@ -0,0 +1,56 @@ +using BlacksmithWorkshopContracts.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshop +{ + 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/BlacksmithWorkshop/BlacksmithWorkshop/FormClients.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormClients.cs index 9ab64db..acde684 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormClients.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormClients.cs @@ -28,28 +28,19 @@ logic) } private void LoadData() { - try - { - var list = _logic.ReadList(null); - if (list != null) + try { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ClientFIO"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["Email"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["Password"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + dataGridView.FillandConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка клиентов"); } - _logger.LogInformation("Загрузка клиентов"); + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки клиентов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка загрузки клиентов"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, - MessageBoxIcon.Error); - } - } private void ButtonUpdate_Click(object sender, EventArgs e) { diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/FormComponents.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormComponents.cs index ae4a014..9fc467c 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormComponents.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormComponents.cs @@ -1,5 +1,6 @@ using BlacksmithWorkshopContracts.BindingModels; using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.DI; using Microsoft.Extensions.Logging; using Microsoft.VisualBasic.Logging; using System; @@ -24,7 +25,7 @@ logic) InitializeComponent(); _logger = logger; _logic = logic; - LoadData(); + } private void FormComponents_Load(object sender, EventArgs e) { @@ -32,54 +33,42 @@ logic) } 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) + } + + 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(); - } - } + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/FormImplementers.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormImplementers.cs index 5dfad67..2d40a72 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormImplementers.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormImplementers.cs @@ -1,5 +1,6 @@ using BlacksmithWorkshopContracts.BindingModels; using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.DI; using Microsoft.Extensions.Logging; using NLog; using System; @@ -31,19 +32,7 @@ logic) { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ImplementerFIO"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["Password"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["WorkExperience"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - - dataGridView.Columns["Qualification"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillandConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка клиентов"); } catch (Exception ex) @@ -52,17 +41,14 @@ logic) MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } + } private void ButtonAdd_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(); } } @@ -70,17 +56,14 @@ Program.ServiceProvider?.GetService(typeof(FormImplementer)); { 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/BlacksmithWorkshop/BlacksmithWorkshop/FormMails.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormMails.cs index adc6a93..bc40240 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormMails.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormMails.cs @@ -28,25 +28,16 @@ namespace BlacksmithWorkshop { try { - var list = _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("Загрузка писем"); + dataGridView.FillandConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка клиентов"); } catch (Exception ex) { - _logger.LogError(ex, "Ошибка загрузки писем"); + _logger.LogError(ex, "Ошибка загрузки клиентов"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } + } private void FormMails_Load(object sender, EventArgs e) diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs index a6cfeca..03738ae 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs @@ -39,13 +39,14 @@ ComponentsManufactueToolStripMenuItem = new ToolStripMenuItem(); OrdersToolStripMenuItem = new ToolStripMenuItem(); запускРаботыToolStripMenuItem = new ToolStripMenuItem(); + письмаToolStripMenuItem = new ToolStripMenuItem(); dataGridView = new DataGridView(); buttonCreateOrder = new Button(); buttonnTakeOrderInWork = new Button(); buttonOrderReady = new Button(); buttonIssuedOrder = new Button(); buttonRef = new Button(); - письмаToolStripMenuItem = new ToolStripMenuItem(); + создатьБэкапToolStripMenuItem = new ToolStripMenuItem(); menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); @@ -53,7 +54,7 @@ // menuStrip1 // menuStrip1.ImageScalingSize = new Size(20, 20); - menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem1, отчётыToolStripMenuItem, запускРаботыToolStripMenuItem, письмаToolStripMenuItem }); + menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem1, отчётыToolStripMenuItem, запускРаботыToolStripMenuItem, письмаToolStripMenuItem, создатьБэкапToolStripMenuItem }); menuStrip1.Location = new Point(0, 0); menuStrip1.Name = "menuStrip1"; menuStrip1.Size = new Size(920, 28); @@ -130,6 +131,13 @@ запускРаботыToolStripMenuItem.Text = "Запуск работы"; запускРаботыToolStripMenuItem.Click += ЗапускРаботыToolStripMenuItem_Click; // + // письмаToolStripMenuItem + // + письмаToolStripMenuItem.Name = "письмаToolStripMenuItem"; + письмаToolStripMenuItem.Size = new Size(77, 24); + письмаToolStripMenuItem.Text = "Письма"; + письмаToolStripMenuItem.Click += ПисьмаToolStripMenuItem_Click; + // // dataGridView // dataGridView.BackgroundColor = SystemColors.ButtonHighlight; @@ -191,12 +199,12 @@ buttonRef.UseVisualStyleBackColor = true; buttonRef.Click += ButtonRef_Click; // - // письмаToolStripMenuItem + // создатьБэкапToolStripMenuItem // - письмаToolStripMenuItem.Name = "письмаToolStripMenuItem"; - письмаToolStripMenuItem.Size = new Size(77, 24); - письмаToolStripMenuItem.Text = "Письма"; - письмаToolStripMenuItem.Click += ПисьмаToolStripMenuItem_Click; + создатьБэкапToolStripMenuItem.Name = "создатьБэкапToolStripMenuItem"; + создатьБэкапToolStripMenuItem.Size = new Size(122, 24); + создатьБэкапToolStripMenuItem.Text = "Создать бэкап"; + создатьБэкапToolStripMenuItem.Click += СоздатьБэкапToolStripMenuItem_Click; // // FormMain // @@ -240,5 +248,6 @@ private ToolStripMenuItem исполнителиToolStripMenuItem; private ToolStripMenuItem запускРаботыToolStripMenuItem; private ToolStripMenuItem письмаToolStripMenuItem; + private ToolStripMenuItem создатьБэкапToolStripMenuItem; } } \ No newline at end of file diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs index 7b8bd7c..5d4447e 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs @@ -1,6 +1,7 @@ using BlacksmithWorkshopBusinessLogic.BusinessLogics; using BlacksmithWorkshopContracts.BindingModels; using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.DI; using BlacksmithWorkshopDataModel.Enums; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; @@ -22,17 +23,19 @@ namespace BlacksmithWorkshop private readonly ILogger _logger; private readonly IOrderLogic _orderLogic; - IReportLogic _reportLogic; + private readonly IReportLogic _reportLogic; + private readonly IBackUpLogic _backUpLogic; private readonly IWorkProcess _workProcess; - 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; - LoadData(); _workProcess = workProcess; + _reportLogic = reportLogic; + _backUpLogic = backUpLogic; + LoadData(); + } private void FormMain_Load(object sender, EventArgs e) @@ -41,54 +44,45 @@ namespace BlacksmithWorkshop } private void LoadData() { - _logger.LogInformation("Загрузка заказов"); try { - var list = _orderLogic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["ManufactureId"].Visible = false; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["ImplementerId"].Visible = false; - - } - _logger.LogInformation("Загрузка компонентов"); + dataGridView.FillandConfigGrid(_orderLogic.ReadList(null)); + _logger.LogInformation("Загрузка клиентов"); } catch (Exception ex) { - _logger.LogError(ex, "Ошибка загрузки компонентов"); + _logger.LogError(ex, "Ошибка загрузки клиентов"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } + } private void КузнечныеИзделияToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormManufactures)); - if (service is FormManufactures form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - form.ShowDialog(); + LoadData(); } } private void КомпонентыToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); - if (service is FormComponents form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - form.ShowDialog(); + LoadData(); } } private void ButtonCreateOrder_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); - if (service is FormCreateOrder form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - form.ShowDialog(); LoadData(); } } @@ -243,48 +237,42 @@ namespace BlacksmithWorkshop private void ComponentsManufactueToolStripMenuItem_Click(object sender, EventArgs e) { - var service = -Program.ServiceProvider?.GetService(typeof(FormReportManufactureComponents)); - if (service is FormReportManufactureComponents form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - form.ShowDialog(); + LoadData(); } + } 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 КлиентыToolStripMenuItem_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); + _workProcess.DoWork(( + DependencyManager.Instance.Resolve() as IImplementerLogic)!, + _orderLogic); MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -292,11 +280,34 @@ Program.ServiceProvider?.GetService(typeof(FormImplementers)); 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(); + if (form.ShowDialog() == DialogResult.OK) { - form.ShowDialog(); + LoadData(); + } + } + + private void СоздатьБэкапToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + 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/BlacksmithWorkshop/BlacksmithWorkshop/FormManufacture.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormManufacture.cs index 5443ddf..c5199bc 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormManufacture.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormManufacture.cs @@ -1,5 +1,6 @@ using BlacksmithWorkshopContracts.BindingModels; using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.DI; using BlacksmithWorkshopContracts.SearchModels; using BlacksmithWorkshopDataModel.Models; using Microsoft.Extensions.Logging; @@ -92,10 +93,7 @@ pc.Value.Item1.ComponentName, pc.Value.Item2 }); private void ButtonAdd_Click(object sender, EventArgs e) { - - var service = Program.ServiceProvider?.GetService(typeof(FormManufactureComponent)); - if (service is FormManufactureComponent form) - { + var form = DependencyManager.Instance.Resolve(); if (form.ShowDialog() == DialogResult.OK) { if (form.ComponentModel == null) @@ -118,15 +116,15 @@ pc.Value.Item1.ComponentName, pc.Value.Item2 }); LoadData(); } - } + } private void ButtonUpd_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormManufactureComponent)); - if (service is FormManufactureComponent form) + var service = DependencyManager.Instance.Resolve(); + if (service is FormManufactureComponent form) { int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/FormManufactures.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormManufactures.cs index fc03d6f..7d3ae09 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormManufactures.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormManufactures.cs @@ -1,5 +1,6 @@ using BlacksmithWorkshopContracts.BindingModels; using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -26,57 +27,45 @@ namespace BlacksmithWorkshop } private void LoadData() { - try - { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ManufactureName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["ManufactureComponents"].Visible = false; - } - _logger.LogInformation("Загрузка компонентов"); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка загрузки компонентов"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, - MessageBoxIcon.Error); - } - } - private void FormManufactures_Load(object sender, EventArgs e) + try + { + dataGridView.FillandConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка клиентов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки клиентов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + private void FormManufactures_Load(object sender, EventArgs e) { LoadData(); } private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormManufacture)); - if (service is FormManufacture 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(FormManufacture)); - if (service is FormManufacture form) - { - form.Id = - Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } - } + } diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs b/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs index bfc515d..3d61c8d 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs @@ -4,6 +4,7 @@ using BlacksmithWorkshopBusinessLogic.OfficePackage; using BlacksmithWorkshopBusinessLogic.OfficePackage.Implements; using BlacksmithWorkshopContracts.BindingModels; using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.DI; using BlacksmithWorkshopContracts.StoragesContracts; using BlacksmithWorkshopDatabaseImplement.Implements; using Microsoft.Extensions.DependencyInjection; @@ -14,8 +15,7 @@ namespace BlacksmithWorkshop { internal static class Program { - private static ServiceProvider? _serviceProvider; - public static ServiceProvider? ServiceProvider => _serviceProvider; + /// /// The main entry point for the application. /// @@ -25,12 +25,11 @@ namespace BlacksmithWorkshop // 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, @@ -46,55 +45,52 @@ namespace BlacksmithWorkshop } catch (Exception ex) { - var logger = _serviceProvider.GetService(); + var logger = DependencyManager.Instance.Resolve(); logger?.LogError(ex, " "); } - Application.Run(_serviceProvider.GetRequiredService()); + Application.Run(DependencyManager.Instance.Resolve()); } - 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(); + private static void InitDependency() + { + 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(); + 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) => ServiceProvider?.GetService()?.MailCheck(); + + private static void MailCheck(object obj) => DependencyManager.Instance.Resolve()?.MailCheck(); } } \ No newline at end of file diff --git a/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogics/BackUpLogic.cs b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogics/BackUpLogic.cs new file mode 100644 index 0000000..e40c07e --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogics/BackUpLogic.cs @@ -0,0 +1,105 @@ +using BlacksmithWorkshopContracts.BindingModels; +using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.StoragesContracts; +using BlacksmithWorkshopDataModel; +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 BlacksmithWorkshopBusinessLogic.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/BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/ColumnAttribute.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..3086bf6 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.Attributes +{ + 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/BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/GridViewAutoSize.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..80ba930 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + None = 1, + ColumnHeader = 2, + AllCellsExceptHeader = 4, + AllCells = 6, + DisplayedCellsExceptHeader = 8, + DisplayedCells = 10, + Fill = 16 + } +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/BackUpSaveBinidngModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/BackUpSaveBinidngModel.cs new file mode 100644 index 0000000..1943d16 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/BackUpSaveBinidngModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.BindingModels +{ + public class BackUpSaveBinidngModel + { + public string FolderName { get; set; } = string.Empty; + } + +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/MessageInfoBindingModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/MessageInfoBindingModel.cs index d419730..2df38ab 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/MessageInfoBindingModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BindingModels/MessageInfoBindingModel.cs @@ -20,5 +20,7 @@ namespace BlacksmithWorkshopContracts.BindingModels public string Subject { get; set; } = string.Empty; public string Body { get; set; } = string.Empty; + + public int Id => throw new NotImplementedException(); } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BlacksmithWorkshopContracts.csproj b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BlacksmithWorkshopContracts.csproj index d82318d..62a4523 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BlacksmithWorkshopContracts.csproj +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BlacksmithWorkshopContracts.csproj @@ -19,6 +19,9 @@ + + + diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IBackUpLogic.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..1ad8778 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,14 @@ +using BlacksmithWorkshopContracts.BindingModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBinidngModel model); + } +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/DependencyManager.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..2da614a --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/DependencyManager.cs @@ -0,0 +1,66 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.DI +{ + public class DependencyManager + { + private readonly IDependencyContainer _dependencyManager; + + private static DependencyManager? _manager; + + private static readonly object _locjObject = new(); + + private DependencyManager() + { + _dependencyManager = new ServiceDependencyContainer(); + } + + 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/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IDependencyContainer.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..f72efb4 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IDependencyContainer.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.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/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IImplementationExtension.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..ec1379c --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/IImplementationExtension.cs @@ -0,0 +1,22 @@ +using BlacksmithWorkshopContracts.DI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.DI +{ + /// + /// Интерфейс для регистрации зависимостей в модулях + /// + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/ServiceDependencyContainer.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..c3d939b --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/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 BlacksmithWorkshopContracts.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/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/ServiceProviderLoader.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..d09cce2 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.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/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/UnityDependencyContainer.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..9bc60f8 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unity; +using Unity.Lifetime; +using Unity.Microsoft.Logging; + +namespace BlacksmithWorkshopContracts.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/BlacksmithWorkshop/BlacksmithWorkshopContracts/StoragesContracts/IBackUpInfo.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..9a11a70 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ClientViewModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ClientViewModel.cs index 1354161..11e959a 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ClientViewModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ClientViewModel.cs @@ -1,4 +1,5 @@ -using BlacksmithWorkshopDataModel.Models; +using BlacksmithWorkshopContracts.Attributes; +using BlacksmithWorkshopDataModel.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,13 +11,17 @@ namespace BlacksmithWorkshopContracts.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: "ФИО клиента", width: 150)] + public string ClientFIO { get; set; } = string.Empty; + + [Column(title: "Логин (эл. почта)", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string Email { get; set; } = string.Empty; + + [Column(title: "Пароль", width: 150)] + public string Password { get; set; } = string.Empty; + } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ComponentViewModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ComponentViewModel.cs index 78ee8a4..554268b 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ComponentViewModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ComponentViewModel.cs @@ -1,4 +1,5 @@ -using BlacksmithWorkshopDataModel.Models; +using BlacksmithWorkshopContracts.Attributes; +using BlacksmithWorkshopDataModel.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,10 +11,11 @@ namespace BlacksmithWorkshopContracts.ViewModels { public class ComponentViewModel : IComponentModel { - public int Id { get; set; } - [DisplayName("Название компонента")] + [Column(visible: false)] + public int Id { get; set; } + [Column(title: "Название компонента", width: 150)] public string ComponentName { get; set; } = string.Empty; - [DisplayName("Цена")] - public double Cost { get; set; } + [Column(title: "цена")] + public double Cost { get; set; } } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ImplementerViewModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ImplementerViewModel.cs index 0fb03e8..0092ea2 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ImplementerViewModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ImplementerViewModel.cs @@ -1,4 +1,5 @@ -using System; +using BlacksmithWorkshopContracts.Attributes; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -9,14 +10,15 @@ namespace BlacksmithWorkshopContracts.ViewModels { public class ImplementerViewModel { - [DisplayName("ФИО")] + [Column(title: "ФИО", width: 150)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column(title: "Пароль", width: 150)] public string Password { get; set; } = string.Empty; - [DisplayName("Опыт работы")] + [Column(title: "Опыт работы", width: 150)] public int WorkExperience { get; set; } - [DisplayName("Квалификация")] + [Column(title: "Квалификация", width: 150)] public int Qualification { get; set; } + [Column(visible: false)] public int Id { get; set; } } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ManufactureViewModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ManufactureViewModel.cs index 210be3c..71c3702 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ManufactureViewModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/ManufactureViewModel.cs @@ -1,4 +1,5 @@ -using BlacksmithWorkshopDataModel.Models; +using BlacksmithWorkshopContracts.Attributes; +using BlacksmithWorkshopDataModel.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,12 +11,14 @@ namespace BlacksmithWorkshopContracts.ViewModels { public class ManufactureViewModel : IManufactureModel { - public int Id { get; set; } - [DisplayName("Название изделия")] - public string ManufactureName { get; set; } = string.Empty; - [DisplayName("Цена")] - public double Price { get; set; } - public Dictionary ManufactureComponents + [Column(visible: false)] + public int Id { get; set; } + [Column(title: "Изделие", width: 150)] + public string ManufactureName { get; set; } = string.Empty; + [Column(title: "Цена", width: 150)] + public double Price { get; set; } + [Column(visible: false)] + public Dictionary ManufactureComponents { get; set; diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/MessageInfoViewModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/MessageInfoViewModel.cs index fdcff50..e409376 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/MessageInfoViewModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/MessageInfoViewModel.cs @@ -1,4 +1,5 @@ -using BlacksmithWorkshopDataModel.Models; +using BlacksmithWorkshopContracts.Attributes; +using BlacksmithWorkshopDataModel.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,20 +11,23 @@ namespace BlacksmithWorkshopContracts.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: "Отправитель", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string SenderName { get; set; } = string.Empty; - [DisplayName("Дата письма")] + [Column(title: "Дата отправки", width: 150)] public DateTime DateDelivery { get; set; } - [DisplayName("Заголовок")] + [Column(title: "Заголовок", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Subject { get; set; } = string.Empty; - [DisplayName("Текст")] + [Column(title: "Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Body { get; set; } = string.Empty; + + public int Id => throw new NotImplementedException(); } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs index ae992f3..7b442aa 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/ViewModels/OrderViewModel.cs @@ -1,4 +1,5 @@ -using BlacksmithWorkshopDataModel.Enums; +using BlacksmithWorkshopContracts.Attributes; +using BlacksmithWorkshopDataModel.Enums; using BlacksmithWorkshopDataModel.Models; using System; using System.Collections.Generic; @@ -11,28 +12,30 @@ namespace BlacksmithWorkshopContracts.ViewModels { public class OrderViewModel : IOrderModel { - [DisplayName("Номер")] - public int Id { get; set; } - - public int ManufactureId { get; set; } - [DisplayName("Изделие")] - public string ManufactureName { get; set; } = string.Empty; - [DisplayName("Исполнитель")] + [Column(title: "Номер", width: 150)] + public int Id { get; set; } + [Column(visible: false)] + public int ManufactureId { get; set; } + [Column(title: "Изделие", width: 150)] + public string ManufactureName { get; set; } = string.Empty; + [Column(title: "Исполнитель", width: 150)] public string? ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Количество")] - public int Count { get; set; } - [DisplayName("Сумма")] + [Column(title: "Количество", width: 150)] + public int Count { get; set; } + [Column(title: "Сумма", width: 150)] - 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; } + public double Sum { get; set; } + [Column(title: "Статус", width: 150)] + public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; + [Column(title: "Дата создания", width: 150)] + public DateTime DateCreate { get; set; } = DateTime.Now; + [Column(title: "Дата выполнения", width: 150)] + public DateTime? DateImplement { get; set; } + [Column(visible: false)] public int ClientId { get; set; } - [DisplayName("Клиент")] + [Column(title: "Клиент", width: 150)] public string ClientFIO { get; set;} = string.Empty; + [Column(visible: false)] public int? ImplementerId { get; set; } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDataModel/Models/IMessageInfoModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopDataModel/Models/IMessageInfoModel.cs index 9923f60..9958b64 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDataModel/Models/IMessageInfoModel.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDataModel/Models/IMessageInfoModel.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace BlacksmithWorkshopDataModel.Models { - public interface IMessageInfoModel + public interface IMessageInfoModel: IId { string MessageId { get; } int? ClientId { get; } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/BlacksmithWorkshopDatabaseImplement.csproj b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/BlacksmithWorkshopDatabaseImplement.csproj index b7abc7b..ca77a3f 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/BlacksmithWorkshopDatabaseImplement.csproj +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/BlacksmithWorkshopDatabaseImplement.csproj @@ -28,4 +28,8 @@ + + + + diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/DatabaseImplementationExtension.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/DatabaseImplementationExtension.cs new file mode 100644 index 0000000..6f21333 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/DatabaseImplementationExtension.cs @@ -0,0 +1,32 @@ +using BlacksmithWorkshopContracts.DI; +using BlacksmithWorkshopContracts.StoragesContracts; +using BlacksmithWorkshopDatabaseImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopDatabaseImplement +{ + 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/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/BackUpInfo.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..62f3778 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/BackUpInfo.cs @@ -0,0 +1,32 @@ +using BlacksmithWorkshopContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopDatabaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new BlacksmithWorkshopDatabase(); + 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/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/ComponentStorage.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/ComponentStorage.cs index 4db089d..2e74bc1 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/ComponentStorage.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Implements/ComponentStorage.cs @@ -15,6 +15,7 @@ namespace BlacksmithWorkshopDatabaseImplement.Implements { public List GetFullList() { + using var context = new BlacksmithWorkshopDatabase(); return context.Components .Select(x => x.GetViewModel) @@ -23,7 +24,8 @@ namespace BlacksmithWorkshopDatabaseImplement.Implements public List GetFilteredList(ComponentSearchModel model) { - if (string.IsNullOrEmpty(model.ComponentName)) + + if (string.IsNullOrEmpty(model.ComponentName)) { return new(); } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Client.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Client.cs index 0288a60..5dee28a 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Client.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Client.cs @@ -5,19 +5,25 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace BlacksmithWorkshopDatabaseImplement.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; public static Client? Create(ClientBindingModel model) diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Component.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Component.cs index 1ec8832..79fc6aa 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Component.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Component.cs @@ -8,18 +8,24 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.Serialization; namespace BlacksmithWorkshopDatabaseImplement.Models { + [DataContract] public class Component : IComponentModel { - - public int Id { get; private set; } - [Required] - public string ComponentName { get; private set; } = string.Empty; - [Required] - public double Cost { get; set; } - [ForeignKey("ComponentId")] + + [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")] public virtual List ManufactureComponents { get; set; } = new(); public static Component? Create(ComponentBindingModel model) diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Implementer.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Implementer.cs index f1049c0..359b1ae 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Implementer.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Implementer.cs @@ -6,22 +6,28 @@ 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 BlacksmithWorkshopDatabaseImplement.Models { + [DataContract] public class Implementer : IImplementerModel { + [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; } - + [DataMember] public int Id { get; set; } [ForeignKey("ImplementerId")] diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Manufacture.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Manufacture.cs index 2e6d8b8..a961afc 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Manufacture.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Manufacture.cs @@ -10,20 +10,27 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.Serialization; namespace BlacksmithWorkshopDatabaseImplement.Models { + [DataContract] public class Manufacture : IManufactureModel { - public int Id { get; set; } + [DataMember] + public int Id { get; set; } + [DataMember] + [Required] + + public string ManufactureName { get; set; } = string.Empty; [Required] - public string ManufactureName { get; set; } = string.Empty; - [Required] - public double Price { get; set; } + [DataMember] + public double Price { get; set; } private Dictionary? _manufactureComponents = null; [NotMapped] - public Dictionary ManufactureComponents + [DataMember] + public Dictionary ManufactureComponents { get { diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/MessageInfo.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/MessageInfo.cs index dbb4cae..2e7a0b1 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/MessageInfo.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/MessageInfo.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; @@ -13,16 +14,17 @@ namespace BlacksmithWorkshopDatabaseImplement.Models public class MessageInfo : IMessageInfoModel { [Key] + [DataMember] public string MessageId { get; private set; } = string.Empty; - - public int? ClientId { get; private set; } - + [DataMember] + public int? ClientId { get; private set; } + [DataMember] public string SenderName { get; private set; } = string.Empty; - + [DataMember] public DateTime DateDelivery { get; private set; } - + [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; } public static MessageInfo? Create(MessageInfoBindingModel model) @@ -52,5 +54,6 @@ namespace BlacksmithWorkshopDatabaseImplement.Models MessageId = MessageId }; + public int Id => throw new NotImplementedException(); } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Order.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Order.cs index 0929e6d..50dd406 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Order.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/Order.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; @@ -14,25 +15,33 @@ namespace BlacksmithWorkshopDatabaseImplement.Models { public class Order : IOrderModel { - public int Id { get; private set; } + [DataMember] + public int Id { get; private set; } + [DataMember] [Required] public int ManufactureId { get; private set; } + [DataMember] [Required] public int Count { get; private set; } [Required] + [DataMember] public double Sum { get; private set; } - public string ManufactureName { get; private set; } = string.Empty; - public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; - - public DateTime DateCreate { get; private set; } = DateTime.Now; - - public DateTime? DateImplement { get; private set; } + [DataMember] + public string ManufactureName { get; private set; } = string.Empty; + [DataMember] + public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; + [DataMember] + public DateTime DateCreate { get; private set; } = DateTime.Now; + [DataMember] + public DateTime? DateImplement { get; private set; } + [DataMember] public int? ImplementerId { get; private set; } public virtual Implementer? Implementer { get; set; } [Required] + [DataMember] public int ClientId { get; private set; } public virtual Client Client { get; set; } public virtual Manufacture Manufacture { get; set; } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/BlacksmithWorkshopFileImplement.csproj b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/BlacksmithWorkshopFileImplement.csproj index bd26c58..3028dc1 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/BlacksmithWorkshopFileImplement.csproj +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/BlacksmithWorkshopFileImplement.csproj @@ -24,4 +24,8 @@ + + + + diff --git a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/FileImplementationExtension.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/FileImplementationExtension.cs new file mode 100644 index 0000000..4cfb5bf --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/FileImplementationExtension.cs @@ -0,0 +1,33 @@ +using BlacksmithWorkshopContracts.DI; +using BlacksmithWorkshopContracts.StoragesContracts; +using BlacksmithWorkshopFileImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopFileImplement +{ + 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/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Implements/BackUpInfo.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..0fb5fee --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Implements/BackUpInfo.cs @@ -0,0 +1,34 @@ +using BlacksmithWorkshopContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopFileImplement.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/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Client.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Client.cs index 90e4c1c..1071323 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Client.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Client.cs @@ -5,20 +5,23 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace BlacksmithWorkshopFileImplement.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/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Component.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Component.cs index ca6cb23..b46e79a 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Component.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Component.cs @@ -4,18 +4,24 @@ using BlacksmithWorkshopDataModel.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 BlacksmithWorkshopFileImplement.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; } - public static Component? Create(ComponentBindingModel model) + [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/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Implementer.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Implementer.cs index 669bfa0..b888c36 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Implementer.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Implementer.cs @@ -4,22 +4,25 @@ using BlacksmithWorkshopDataModel.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 BlacksmithWorkshopFileImplement.Models { + [DataContract] public class Implementer : IImplementerModel { + [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; } - + [DataMember] public int Id { get; private set; } public static Implementer? Create(ImplementerBindingModel model) { diff --git a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Manufacture.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Manufacture.cs index df8277a..fed17c1 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Manufacture.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Manufacture.cs @@ -4,21 +4,27 @@ using BlacksmithWorkshopDataModel.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 BlacksmithWorkshopFileImplement.Models { + [DataContract] public class Manufacture: IManufactureModel { - public int Id { get; private set; } - public string ManufactureName { get; private set; } = string.Empty; - public double Price { get; private set; } + [DataMember] + public int Id { get; private set; } + [DataMember] + public string ManufactureName { get; private set; } = string.Empty; + [DataMember] + public double Price { get; private set; } public Dictionary Components { get; private set; } = new(); private Dictionary? _manufactureComponents = null; - public Dictionary ManufactureComponents + [DataMember] + public Dictionary ManufactureComponents { get { diff --git a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/MessageInfo.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/MessageInfo.cs index 961bfc1..505a688 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/MessageInfo.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/MessageInfo.cs @@ -4,24 +4,27 @@ using BlacksmithWorkshopDataModel.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 BlacksmithWorkshopFileImplement.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) @@ -76,5 +79,7 @@ namespace BlacksmithWorkshopFileImplement.Models new XAttribute("SenderName", SenderName), new XAttribute("DateDelivery", DateDelivery) ); + + public int Id => throw new NotImplementedException(); } } diff --git a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs index 6028159..4265f25 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopFileImplement/Models/Order.cs @@ -6,28 +6,35 @@ 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 BlacksmithWorkshopFileImplement.Models { + [DataContract] public class Order : IOrderModel { - public int ManufactureId { get; private set; } - - public int Count { get; private set; } - + [DataMember] + public int ManufactureId { get; private set; } + [DataMember] + public int Count { get; private set; } + [DataMember] public double Sum { get; private set; } + [DataMember] public string ManufactureName { get; private set; } = string.Empty; - public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; + [DataMember] + public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; - public DateTime DateCreate { get; private set; } = DateTime.Now; - - public DateTime? DateImplement { get; private set; } - - public int Id { get; private set; } - public int ClientId { get; private set; } + [DataMember] + public DateTime DateCreate { get; private set; } = DateTime.Now; + [DataMember] + public DateTime? DateImplement { get; private set; } + [DataMember] + public int Id { get; private set; } + [DataMember] + public int ClientId { get; private set; } public static Order? Create(OrderBindingModel model) { if (model == null) diff --git a/BlacksmithWorkshop/BlacksmithWorkshopListImplement/BlacksmithWorkshopListImplement.csproj b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/BlacksmithWorkshopListImplement.csproj index 1d28130..4578876 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopListImplement/BlacksmithWorkshopListImplement.csproj +++ b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/BlacksmithWorkshopListImplement.csproj @@ -25,4 +25,8 @@ + + + + diff --git a/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Implements/BackUpInfo.cs b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..2f3a09d --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Implements/BackUpInfo.cs @@ -0,0 +1,22 @@ +using BlacksmithWorkshopContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopListImplement.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/BlacksmithWorkshop/BlacksmithWorkshopListImplement/ListImplementationExtension.cs b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/ListImplementationExtension.cs new file mode 100644 index 0000000..4f5bc62 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/ListImplementationExtension.cs @@ -0,0 +1,32 @@ +using BlacksmithWorkshopContracts.DI; +using BlacksmithWorkshopContracts.StoragesContracts; +using BlacksmithWorkshopListImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopListImplement +{ + 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/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/MessageInfo.cs b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/MessageInfo.cs index 9061ca6..cbdf29a 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/MessageInfo.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshopListImplement/Models/MessageInfo.cs @@ -49,5 +49,7 @@ namespace BlacksmithWorkshopListImplement.Models SenderName = SenderName, DateDelivery = DateDelivery, }; + + public int Id => throw new NotImplementedException(); } } diff --git a/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopContracts.dll b/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..7427eaa7c93a76e329988eeda71ac57be61ce7e9 GIT binary patch literal 31744 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 literal 0 HcmV?d00001 diff --git a/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopDataModel.dll b/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopDataModel.dll new file mode 100644 index 0000000000000000000000000000000000000000..cc64f286f49c93d85821eb98684a0077335285c5 GIT binary patch literal 6144 zcmeHLYiu0V6+ZLudTnDT&Vv{dk|7Ub0$m(JXhR{`-nD~EoH$v>3Dl}RyE|SFnVnh9 z%sR0uzzr|8v<-!*f(p_$Y7uRP8UYbj%0np{q$*~SzNhw3p_W>K;5?DcpE*_^y;Ov z($-fm9iB8jt>`*=S1)K;-L@TH%NUwlvNhAzQrpv7!O0nk*4F0Lq3fYOqOFobuRQkA z)0MmZnpSEpQWw#DNMeEX?W=Ir(7VxDqXFe0ZWeI-qRjvy=cds3J;Dk5VQ1o6y|9oT zf#2;+bQ6`i5NEb=q6;9~pCB4OQ+F<2BZ^1#aqu@q_=Iol_rbqA4*;ErEsPtSXd2OY z!u8xNI1yVn2u^eXdZcwD`h;s(4h%U~8b@be7ota6H&Jhd738a2S2T`IrUp8s5&f=} zNMhl6w3TuvMmN*COi0K}zOoqZ)?BDOdOMt|>o!*u%2_;OR@WiO^k;gdFapkJ>Y7AX zVnf%4^_w`L2C{%xVqL7dgXm#gM;kz=eb=<}9$UQI5|nAxt~8wj&C|YW%dUYGu5md0 zCE{4sYdIM}d^GDpGo;;7s(OJgJ5eXuSK-P%s#bIYXe4&ji zOtW=Do>OA_&ke%Skc(U8M!+4Y za;yv5%dPupG{W`bajEG>lqmOuI^C%{?)PdgGVZE6UH!Np*WK@s621Eyb>n6!>hr7W zWaJKaz%p1}L@&1YWkYi)wV-J9XTb5n0XWuhb}apOTB{o>1?Oa4V(g z9bQqt7||V$_>9paYDABtH=#G9w+MO`Pe?oQ3|<6mrptj?p8_`t>=8I1aEHKK1nR&T zO#>H`Dd;$!@YUiTmjgQ}0bE8KfEs-Ynv3Z*X$>~bo1tl;p8yxq9B?VU16)NP0I#4= zN(qeF1N<~)fk`R?Zx-@2FiD?o6@e^}vBzYy~0h;1HJ4+9Sf$q{-I^dANNk$MdDODcPQSKtG} z!*5jfaKFN1XVv4t%OtjZO??q~1UCE&q5xyKa`cVBIHH$D1~PJJ1>HjPfEQr?W$+7u zZP;sNNS6TTV@1f&Ed?&1OMnZpN61(;mjV}KzGQ6BYk*5=EwBS?N5+^dfEUvzfJ^Br z;4-Wx8RItqm(xa4XRys7&RXLgj`#CQTS^OsLA~s@>Z=89D_NGFv5fKcG@@H2W4KfV zb2X*RtZzED?oNZbe$dI4EMqg}4S#H)0E>cQ`-a;;uw96fmIY|`}P;%-mpVa#L+gr5SXP6J7>66Ht7_Kj*Y;DB&GYtunEgB^qnQ!XO>fDUD7px z)K|zDxtx*f@$uuFDM7++Ov`XZelUrssz$pw#VSWBBU8%fx$HGrWg=>l9?vrh8Ebmj z^rMEux{H|l@j7at6noFM??*HvhU;Pa&Q=cC6OLQZ#oSu|)GF!N6K1~T3cH$m}>g6qV%QmtPWVipmJ~tlQHyMOc0z_sxuHnSMmuJB`BkTYCPC z*-C^N;kAi+Ej_!}E13QyFAs0hDPkIRtYpKYfynZxNWyi9`h=40E>=rOM;3i33D#wW zsVt>{=QYz;&`s-HK_qgP6^1VsS-Mo9J{!QJca(I?oG`PZ!qp^=iSTKnMAmoQiacfN zdE4=PGwW4EVfpX?28%OoxKnsqym0BEJ{+l6ef+tW9u1mV*YTVQALDXHkF8tNp6Q)4 z36b!*O*pA)V38exs^l8>qU!EA z>SS&k6~!F24IkD2nDJHPL@}44^i4fiZ@iYmK>xBR43vv8@xCNay?0VNaqmZCC&Gg{ zXZ9x38dGPt$^kymjA6;7ENf6VZ7O(KtRF*co#D9CYvAV0vPFDKLfJty6A^+8<_t^Z zEIHfpw}U<1L_SY%*nH(0P$QJ4F<>9<1T}y!E!)5k0Q-ZlF7&+mr@sd?U0D^u^~TT- zKia%LqAdkRf>)hf_%ZQ4z<^JiCdd(HtBFSqL#spTL9de!I|p3Qj;gQ2sf3t(SecOL zKgQEhVbevGziTK18oA=#Qo>2Vp#l}fJ*JV74$ctnd&M2Iv={d-z`IYAv>Vp0kW7Lq z;*85N=`;u~hjIK(V_f*HWR!x`!|8$JE7rw-zW%$g4N28JN8sPZ9cp!1kCRPTwR1cg z?76bOu(c7d70LAc;z%H0OXS;$nZ*VI-+AGgD_X?Kjx)}qX8e6jL!T6JY!Br;TO3EF zPRs?B|8L_7=5+}7;W;Ux_I@N={&>bK=|7*>E}SwXs`q)f3pJr0Ak;AvH$=8 literal 0 HcmV?d00001 diff --git a/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopDatabaseImplement.dll b/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopDatabaseImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..bf27cef394add18c4a30b84865dfa57deb152a61 GIT binary patch literal 75776 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 literal 0 HcmV?d00001 diff --git a/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopFileImplement.dll b/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopFileImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..c96669e376b339951b271b07da477fcef930dc2e GIT binary patch literal 39936 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 literal 0 HcmV?d00001 diff --git a/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopListImplement.dll b/BlacksmithWorkshop/ImplementationExtensions/BlacksmithWorkshopListImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..42870fa378fd587db25bbccfe01b82d10f7fce65 GIT binary patch literal 25088 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