From 5eea91c76d08b2ea1385f003aac07c0be1c027f7 Mon Sep 17 00:00:00 2001 From: Ino Date: Tue, 11 Apr 2023 16:57:04 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BA=D0=BE=D0=B5=20=D1=87=D1=82=D0=BE=20?= =?UTF-8?q?=D0=B5=D1=89=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/BackUpLogic.cs | 98 +++++++++++++++ IceCreamShop/IceCreamShop/FormComponents.cs | 39 +++--- IceCreamShop/IceCreamShop/FormIceCream.cs | 79 ++++++------ IceCreamShop/IceCreamShop/FormIceCreams.cs | 33 +++-- IceCreamShop/IceCreamShop/FormImplementers.cs | 33 +++-- .../IceCreamShop/FormMain.Designer.cs | 11 +- IceCreamShop/IceCreamShop/FormMain.cs | 90 +++++++------- IceCreamShop/IceCreamShop/Program.cs | 115 ++++++++---------- .../BindingModels/BackUpSaveBinidngModel.cs | 7 ++ .../BindingModels/MessageInfoBindingModel.cs | 4 +- .../BusinessLogicsContracts/IBackUpLogic.cs | 9 ++ .../DI/DependencyManager.cs | 61 ++++++++++ .../DI/IDependencyContainer.cs | 35 ++++++ .../DI/IImplementationExtension.cs | 11 ++ .../DI/ServiceDependencyContainer.cs | 57 +++++++++ .../DI/ServiceProviderLoader.cs | 50 ++++++++ .../DI/UnityDependencyContainer.cs | 38 ++++++ .../IceCreamShopContracts.csproj | 2 + .../StoragesContracts/IBackUpInfo.cs | 8 ++ .../ViewModels/MessageInfoViewModel.cs | 2 +- .../Models/IMessageInfoModel.cs | 2 +- .../Implements/BackUpInfo.cs | 26 ++++ .../Models/MessageInfo.cs | 4 +- .../Models/MessageInfo.cs | 4 +- .../IceCreamShopListImplement.csproj | 4 + .../Implements/BackUpInfo.cs | 17 +++ .../Implements/MessageInfoStorage.cs | 5 +- .../ListImplementationExtension.cs | 23 ++++ .../Models/MessageInfo.cs | 3 +- .../IceCreamShopContracts.dll | Bin 0 -> 31744 bytes .../IceCreamShopDataModels.dll | Bin 0 -> 6144 bytes .../IceCreamShopListImplement.dll | Bin 0 -> 26112 bytes 32 files changed, 657 insertions(+), 213 deletions(-) create mode 100644 IceCreamShop/IceCreamBusinessLogic/BusinessLogics/BackUpLogic.cs create mode 100644 IceCreamShop/IceCreamShopContracts/BindingModels/BackUpSaveBinidngModel.cs create mode 100644 IceCreamShop/IceCreamShopContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 IceCreamShop/IceCreamShopContracts/DI/DependencyManager.cs create mode 100644 IceCreamShop/IceCreamShopContracts/DI/IDependencyContainer.cs create mode 100644 IceCreamShop/IceCreamShopContracts/DI/IImplementationExtension.cs create mode 100644 IceCreamShop/IceCreamShopContracts/DI/ServiceDependencyContainer.cs create mode 100644 IceCreamShop/IceCreamShopContracts/DI/ServiceProviderLoader.cs create mode 100644 IceCreamShop/IceCreamShopContracts/DI/UnityDependencyContainer.cs create mode 100644 IceCreamShop/IceCreamShopContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 IceCreamShop/IceCreamShopDatabaseImplement/Implements/BackUpInfo.cs create mode 100644 IceCreamShop/IceCreamShopListImplement/Implements/BackUpInfo.cs create mode 100644 IceCreamShop/IceCreamShopListImplement/ListImplementationExtension.cs create mode 100644 IceCreamShop/ImplementationExtensions/IceCreamShopContracts.dll create mode 100644 IceCreamShop/ImplementationExtensions/IceCreamShopDataModels.dll create mode 100644 IceCreamShop/ImplementationExtensions/IceCreamShopListImplement.dll diff --git a/IceCreamShop/IceCreamBusinessLogic/BusinessLogics/BackUpLogic.cs b/IceCreamShop/IceCreamBusinessLogic/BusinessLogics/BackUpLogic.cs new file mode 100644 index 0000000..7ad268c --- /dev/null +++ b/IceCreamShop/IceCreamBusinessLogic/BusinessLogics/BackUpLogic.cs @@ -0,0 +1,98 @@ +using IceCreamShopContracts.BindingModels; +using IceCreamShopContracts.BusinessLogicsContracts; +using IceCreamShopContracts.StoragesContracts; +using AbstractIceCreamShopDataModels; +using Microsoft.Extensions.Logging; +using System.IO.Compression; +using System.Reflection; +using System.Runtime.Serialization.Json; + +namespace ConfectioneryBusinessLogic +{ + 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/IceCreamShop/IceCreamShop/FormComponents.cs b/IceCreamShop/IceCreamShop/FormComponents.cs index 1187925..f47aea7 100644 --- a/IceCreamShop/IceCreamShop/FormComponents.cs +++ b/IceCreamShop/IceCreamShop/FormComponents.cs @@ -10,6 +10,7 @@ using System.Windows.Forms; using IceCreamShop; using IceCreamShopContracts.BindingModels; using IceCreamShopContracts.BusinessLogicsContracts; +using IceCreamShopContracts.DI; using IceCreamShopContracts.SearchModels; using Microsoft.Extensions.Logging; @@ -48,31 +49,25 @@ namespace IceCreamShopView 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 buttonChange_Click(object sender, EventArgs e) { - if (dataGridView.SelectedRows.Count == 1) - { - var service = - Program.ServiceProvider?.GetService(typeof(FormComponent)); - if (service is FormComponent form) - { - form.Id = - Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - if (form.ShowDialog() == DialogResult.OK) - LoadData(); - } - } - } + if (dataGridView.SelectedRows.Count == 1) + { + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } private void buttonDelete_Click(object sender, EventArgs e) { diff --git a/IceCreamShop/IceCreamShop/FormIceCream.cs b/IceCreamShop/IceCreamShop/FormIceCream.cs index 58dee6b..99e40d5 100644 --- a/IceCreamShop/IceCreamShop/FormIceCream.cs +++ b/IceCreamShop/IceCreamShop/FormIceCream.cs @@ -11,6 +11,7 @@ using AbstractIceCreamShopDataModels.Models; using IceCreamShop; using IceCreamShopContracts.BindingModels; using IceCreamShopContracts.BusinessLogicsContracts; +using IceCreamShopContracts.DI; using IceCreamShopContracts.SearchModels; using IceCreamShopContracts.ViewModels; using Microsoft.Extensions.Logging; @@ -98,51 +99,49 @@ namespace IceCreamShopView private void buttonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormIceCreamComponent)); - if (service is FormIceCreamComponent form) - { - if (form.ShowDialog() == DialogResult.OK) - { - if (form.ComponentModel == null) - { - return; - } - _logger.LogInformation("Добавление нового компонента:{ ComponentName}- { Count}", form.ComponentModel.ComponentName, form.Count); - if (_iceCreamComponents.ContainsKey(form.Id)) - { - _iceCreamComponents[form.Id] = (form.ComponentModel, form.Count); - } - else - { - _iceCreamComponents.Add(form.Id, (form.ComponentModel, form.Count)); - } - LoadData(); - } - } - } + 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 (_iceCreamComponents.ContainsKey(form.Id)) + { + _iceCreamComponents[form.Id] = (form.ComponentModel, + form.Count); + } + else + { + _iceCreamComponents.Add(form.Id, (form.ComponentModel, + form.Count)); + } + LoadData(); + } + } private void buttonEdit_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormIceCreamComponent)); - if (service is FormIceCreamComponent form) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); - form.Id = id; - form.Count = _iceCreamComponents[id].Item2; - if (form.ShowDialog() == DialogResult.OK) - { - if (form.ComponentModel == null) - { - return; - } - _logger.LogInformation("Изменение компонента:{ ComponentName}- { Count}", form.ComponentModel.ComponentName, form.Count); - _iceCreamComponents[form.Id] = (form.ComponentModel, form.Count); - LoadData(); - } - } - } + var form = DependencyManager.Instance.Resolve(); + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); + form.Id = id; + form.Count = _iceCreamComponents[id].Item2; + if (form.ShowDialog() == DialogResult.OK) + { + if (form.ComponentModel == null) + { + return; + } + _logger.LogInformation("Изменение компонента: { ComponentName} - { Count} ", + form.ComponentModel.ComponentName, form.Count); + _iceCreamComponents[id] = (form.ComponentModel, form.Count); + LoadData(); + } + } } private void buttonDelete_Click(object sender, EventArgs e) diff --git a/IceCreamShop/IceCreamShop/FormIceCreams.cs b/IceCreamShop/IceCreamShop/FormIceCreams.cs index 869e891..242dd2b 100644 --- a/IceCreamShop/IceCreamShop/FormIceCreams.cs +++ b/IceCreamShop/IceCreamShop/FormIceCreams.cs @@ -10,6 +10,7 @@ using System.Windows.Forms; using IceCreamShop; using IceCreamShopContracts.BindingModels; using IceCreamShopContracts.BusinessLogicsContracts; +using IceCreamShopContracts.DI; using Microsoft.Extensions.Logging; @@ -48,30 +49,24 @@ namespace IceCreamShopView private void buttonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormIceCream)); - if (service is FormIceCream form) - { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } - } - } + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } private void buttonEdit_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormIceCream)); - if (service is FormIceCream 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(); + } + } } private void buttonDelete_Click(object sender, EventArgs e) diff --git a/IceCreamShop/IceCreamShop/FormImplementers.cs b/IceCreamShop/IceCreamShop/FormImplementers.cs index 4d27954..77dcb0a 100644 --- a/IceCreamShop/IceCreamShop/FormImplementers.cs +++ b/IceCreamShop/IceCreamShop/FormImplementers.cs @@ -1,6 +1,7 @@ using IceCreamShop; using IceCreamShopContracts.BindingModels; using IceCreamShopContracts.BusinessLogicsContracts; +using IceCreamShopContracts.DI; using Microsoft.Extensions.Logging; @@ -39,30 +40,24 @@ namespace IceCreamShopView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); - if (service is FormImplementer 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(FormImplementer)); - if (service is FormImplementer 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(); + } + } } private void ButtonDel_Click(object sender, EventArgs e) diff --git a/IceCreamShop/IceCreamShop/FormMain.Designer.cs b/IceCreamShop/IceCreamShop/FormMain.Designer.cs index 8b20033..99c3e51 100644 --- a/IceCreamShop/IceCreamShop/FormMain.Designer.cs +++ b/IceCreamShop/IceCreamShop/FormMain.Designer.cs @@ -44,6 +44,7 @@ ordersToolStripMenuItem = new ToolStripMenuItem(); DoWorkToolStripMenuItem = new ToolStripMenuItem(); MailToolStripMenuItem = new ToolStripMenuItem(); + createBackupToolStripMenuItem = new ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); menuStrip.SuspendLayout(); SuspendLayout(); @@ -95,7 +96,7 @@ // menuStrip // menuStrip.ImageScalingSize = new Size(20, 20); - menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчетыToolStripMenuItem, DoWorkToolStripMenuItem, MailToolStripMenuItem }); + menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчетыToolStripMenuItem, DoWorkToolStripMenuItem, MailToolStripMenuItem, createBackupToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; menuStrip.Padding = new Padding(5, 2, 0, 2); @@ -180,6 +181,13 @@ MailToolStripMenuItem.Text = "Письма"; MailToolStripMenuItem.Click += MailToolStripMenuItem_Click; // + // createBackupToolStripMenuItem + // + createBackupToolStripMenuItem.Name = "createBackupToolStripMenuItem"; + createBackupToolStripMenuItem.Size = new Size(97, 20); + createBackupToolStripMenuItem.Text = "Создать бекап"; + createBackupToolStripMenuItem.Click += createBackupToolStripMenuItem_Click; + // // FormMain // AutoScaleDimensions = new SizeF(7F, 15F); @@ -218,5 +226,6 @@ private ToolStripMenuItem ImplementersToolStripMenuItem; private ToolStripMenuItem DoWorkToolStripMenuItem; private ToolStripMenuItem MailToolStripMenuItem; + private ToolStripMenuItem createBackupToolStripMenuItem; } } \ No newline at end of file diff --git a/IceCreamShop/IceCreamShop/FormMain.cs b/IceCreamShop/IceCreamShop/FormMain.cs index 13c3116..15afee0 100644 --- a/IceCreamShop/IceCreamShop/FormMain.cs +++ b/IceCreamShop/IceCreamShop/FormMain.cs @@ -1,8 +1,10 @@ using AbstractIceCreamShopDataModels.Enums; +using ConfectioneryBusinessLogic; using IceCreamBusinessLogic.BusinessLogics; using IceCreamShop; using IceCreamShopContracts.BindingModels; using IceCreamShopContracts.BusinessLogicsContracts; +using IceCreamShopContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -22,13 +24,15 @@ namespace IceCreamShopView private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; private readonly IWorkProcess _workProcess; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) + private readonly IBackUpLogic _backUpLogic; + public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess, IBackUpLogic backUpLogic) { InitializeComponent(); _logger = logger; _orderLogic = orderLogic; _reportLogic = reportLogic; _workProcess = workProcess; + _backUpLogic = backUpLogic; } private void FormMain_Load(object sender, EventArgs e) @@ -53,30 +57,21 @@ namespace IceCreamShopView private void компонентыToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); - if (service is FormComponents form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void мороженоеToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormIceCreams)); - if (service is FormIceCreams form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void buttonCreateOrder_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); - if (service is FormCreateOrder form) - { - form.ShowDialog(); - LoadData(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); + LoadData(); } private void buttonSetToWork_Click(object sender, EventArgs e) @@ -176,54 +171,65 @@ namespace IceCreamShopView private void IceCreamComponentsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportProductComponents)); - if (service is FormReportProductComponents form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void OrdersToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders)); - if (service is FormReportOrders form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void клиенты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 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 DoWorkToolStripMenuItem_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 MailToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormViewMail)); - if (service is FormViewMail 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 BackUpSaveBinidngModel + { + FolderName = fbd.SelectedPath + }); + MessageBox.Show("Бекап создан", "Сообщение", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); } } } diff --git a/IceCreamShop/IceCreamShop/Program.cs b/IceCreamShop/IceCreamShop/Program.cs index 9383722..16bc257 100644 --- a/IceCreamShop/IceCreamShop/Program.cs +++ b/IceCreamShop/IceCreamShop/Program.cs @@ -1,8 +1,6 @@ using IceCreamShopContracts.BusinessLogicsContracts; -using IceCreamShopContracts.StoragesContracts; using IceCreamBusinessLogic.BusinessLogics; using IceCreamShopView; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NLog.Extensions.Logging; using IceCreamBusinessLogic.OfficePackage.Implements; @@ -11,13 +9,12 @@ using IceCreamShopDatabaseImplement.Implements; using IceCreamBusinessLogic.BusinessLogic; using IceCreamBusinessLogic.MailWorker; using IceCreamShopContracts.BindingModels; +using IceCreamShopContracts.DI; namespace IceCreamShop { internal static class Program { - private static ServiceProvider? _serviceProvider; - public static ServiceProvider? ServiceProvider => _serviceProvider; /// /// The main entry point for the application. /// @@ -27,14 +24,12 @@ namespace IceCreamShop // 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 + try { - var mailSender = _serviceProvider.GetService(); - mailSender?.MailConfig(new MailConfigBindingModel + var mailSender = DependencyManager.Instance.Resolve(); + mailSender?.MailConfig(new MailConfigBindingModel { MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty, MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty, @@ -47,58 +42,54 @@ namespace IceCreamShop // var timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 100000); } - catch (Exception ex) - { - var logger = _serviceProvider.GetService(); - logger?.LogError(ex, " "); - } + catch (Exception ex) + { + var logger = DependencyManager.Instance.Resolve(); + logger?.LogError(ex, " "); + } - Application.Run(_serviceProvider.GetRequiredService()); - } - - private static void ConfigureServices(ServiceCollection services) - { - services.AddLogging(option => - { - option.SetMinimumLevel(LogLevel.Information); - option.AddNLog("nlog.config"); - }); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddSingleton(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + Application.Run(DependencyManager.Instance.Resolve()); } - private static void MailCheck(object obj) => ServiceProvider?.GetService()?.MailCheck(); - } + + private static void InitDependency() + { + DependencyManager.InitDependency(); + + DependencyManager.Instance.AddLogging(option => + { + option.SetMinimumLevel(LogLevel.Information); + option.AddNLog("nlog.config"); + }); + + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + + DependencyManager.Instance.RegisterType(); + + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + private static void MailCheck(object obj) => DependencyManager.Instance.Resolve()?.MailCheck(); + } } \ No newline at end of file diff --git a/IceCreamShop/IceCreamShopContracts/BindingModels/BackUpSaveBinidngModel.cs b/IceCreamShop/IceCreamShopContracts/BindingModels/BackUpSaveBinidngModel.cs new file mode 100644 index 0000000..bb8d08e --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/BindingModels/BackUpSaveBinidngModel.cs @@ -0,0 +1,7 @@ +namespace IceCreamShopContracts.BindingModels +{ + public class BackUpSaveBinidngModel + { + public string FolderName { get; set; } = string.Empty; + } +} diff --git a/IceCreamShop/IceCreamShopContracts/BindingModels/MessageInfoBindingModel.cs b/IceCreamShop/IceCreamShopContracts/BindingModels/MessageInfoBindingModel.cs index 7bab4ca..1583bd9 100644 --- a/IceCreamShop/IceCreamShopContracts/BindingModels/MessageInfoBindingModel.cs +++ b/IceCreamShop/IceCreamShopContracts/BindingModels/MessageInfoBindingModel.cs @@ -15,5 +15,7 @@ namespace IceCreamShopContracts.BindingModels public string Body { get; set; } = string.Empty; public DateTime DateDelivery { get; set; } - } + + public int Id => throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/IceCreamShop/IceCreamShopContracts/BusinessLogicsContracts/IBackUpLogic.cs b/IceCreamShop/IceCreamShopContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..3112267 --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,9 @@ +using IceCreamShopContracts.BindingModels; + +namespace IceCreamShopContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBinidngModel model); + } +} diff --git a/IceCreamShop/IceCreamShopContracts/DI/DependencyManager.cs b/IceCreamShop/IceCreamShopContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..93cda26 --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/DI/DependencyManager.cs @@ -0,0 +1,61 @@ +using Microsoft.Extensions.Logging; + +namespace IceCreamShopContracts.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/IceCreamShop/IceCreamShopContracts/DI/IDependencyContainer.cs b/IceCreamShop/IceCreamShopContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..8bcedb8 --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/DI/IDependencyContainer.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Logging; + +namespace IceCreamShopContracts.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/IceCreamShop/IceCreamShopContracts/DI/IImplementationExtension.cs b/IceCreamShop/IceCreamShopContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..2ce94d6 --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/DI/IImplementationExtension.cs @@ -0,0 +1,11 @@ +namespace IceCreamShopContracts.DI +{ + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} diff --git a/IceCreamShop/IceCreamShopContracts/DI/ServiceDependencyContainer.cs b/IceCreamShop/IceCreamShopContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..a1b760d --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/DI/ServiceDependencyContainer.cs @@ -0,0 +1,57 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace IceCreamShopContracts.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/IceCreamShop/IceCreamShopContracts/DI/ServiceProviderLoader.cs b/IceCreamShop/IceCreamShopContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..7348816 --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,50 @@ +using System.Reflection; + +namespace IceCreamShopContracts.DI +{ + public 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/IceCreamShop/IceCreamShopContracts/DI/UnityDependencyContainer.cs b/IceCreamShop/IceCreamShopContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..bfcd38f --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Logging; +using Unity; +using Unity.Microsoft.Logging; + +namespace IceCreamShopContracts.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/IceCreamShop/IceCreamShopContracts/IceCreamShopContracts.csproj b/IceCreamShop/IceCreamShopContracts/IceCreamShopContracts.csproj index 981e7c0..f8071fb 100644 --- a/IceCreamShop/IceCreamShopContracts/IceCreamShopContracts.csproj +++ b/IceCreamShop/IceCreamShopContracts/IceCreamShopContracts.csproj @@ -9,6 +9,8 @@ + + diff --git a/IceCreamShop/IceCreamShopContracts/StoragesContracts/IBackUpInfo.cs b/IceCreamShop/IceCreamShopContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..bafd27b --- /dev/null +++ b/IceCreamShop/IceCreamShopContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,8 @@ +namespace IceCreamShopContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} diff --git a/IceCreamShop/IceCreamShopContracts/ViewModels/MessageInfoViewModel.cs b/IceCreamShop/IceCreamShopContracts/ViewModels/MessageInfoViewModel.cs index 627d1d0..0db37eb 100644 --- a/IceCreamShop/IceCreamShopContracts/ViewModels/MessageInfoViewModel.cs +++ b/IceCreamShop/IceCreamShopContracts/ViewModels/MessageInfoViewModel.cs @@ -1,6 +1,5 @@ using AbstractIceCreamShopDataModels.Models; using IceCreamShopContracts.Attributes; -using System.ComponentModel; namespace IceCreamShopContracts.ViewModels { @@ -25,5 +24,6 @@ namespace IceCreamShopContracts.ViewModels public string Body { get; set; } = string.Empty; [Column(visible: false)] + public int Id => throw new NotImplementedException(); } } \ No newline at end of file diff --git a/IceCreamShop/IceCreamShopDataModels/Models/IMessageInfoModel.cs b/IceCreamShop/IceCreamShopDataModels/Models/IMessageInfoModel.cs index ac4fccb..0a7f17c 100644 --- a/IceCreamShop/IceCreamShopDataModels/Models/IMessageInfoModel.cs +++ b/IceCreamShop/IceCreamShopDataModels/Models/IMessageInfoModel.cs @@ -1,6 +1,6 @@ namespace AbstractIceCreamShopDataModels.Models { - public interface IMessageInfoModel + public interface IMessageInfoModel : IId { string MessageId { get; } int? ClientId { get; } diff --git a/IceCreamShop/IceCreamShopDatabaseImplement/Implements/BackUpInfo.cs b/IceCreamShop/IceCreamShopDatabaseImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..1e2c4e7 --- /dev/null +++ b/IceCreamShop/IceCreamShopDatabaseImplement/Implements/BackUpInfo.cs @@ -0,0 +1,26 @@ +using IceCreamShopContracts.StoragesContracts; + +namespace IceCreamShopDatabaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new IceCreamShopDatabase(); + 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/IceCreamShop/IceCreamShopDatabaseImplement/Models/MessageInfo.cs b/IceCreamShop/IceCreamShopDatabaseImplement/Models/MessageInfo.cs index 9c6b65b..6e95abf 100644 --- a/IceCreamShop/IceCreamShopDatabaseImplement/Models/MessageInfo.cs +++ b/IceCreamShop/IceCreamShopDatabaseImplement/Models/MessageInfo.cs @@ -48,5 +48,7 @@ namespace IceCreamShopDatabaseImplement.Models SenderName = SenderName, DateDelivery = DateDelivery, }; - } + + public int Id => throw new NotImplementedException(); + } } diff --git a/IceCreamShop/IceCreamShopFileImplement/Models/MessageInfo.cs b/IceCreamShop/IceCreamShopFileImplement/Models/MessageInfo.cs index aa31ba3..244d052 100644 --- a/IceCreamShop/IceCreamShopFileImplement/Models/MessageInfo.cs +++ b/IceCreamShop/IceCreamShopFileImplement/Models/MessageInfo.cs @@ -71,5 +71,7 @@ namespace IceCreamShopFileImplement.Models new XAttribute("SenderName", SenderName), new XAttribute("DateDelivery", DateDelivery) ); - } + + public int Id => throw new NotImplementedException(); + } } diff --git a/IceCreamShop/IceCreamShopListImplement/IceCreamShopListImplement.csproj b/IceCreamShop/IceCreamShopListImplement/IceCreamShopListImplement.csproj index b6d75cd..79e43c9 100644 --- a/IceCreamShop/IceCreamShopListImplement/IceCreamShopListImplement.csproj +++ b/IceCreamShop/IceCreamShopListImplement/IceCreamShopListImplement.csproj @@ -15,4 +15,8 @@ + + + + diff --git a/IceCreamShop/IceCreamShopListImplement/Implements/BackUpInfo.cs b/IceCreamShop/IceCreamShopListImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..6693a95 --- /dev/null +++ b/IceCreamShop/IceCreamShopListImplement/Implements/BackUpInfo.cs @@ -0,0 +1,17 @@ +using IceCreamShopContracts.StoragesContracts; + +namespace IceCreamShopListImplement.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/IceCreamShop/IceCreamShopListImplement/Implements/MessageInfoStorage.cs b/IceCreamShop/IceCreamShopListImplement/Implements/MessageInfoStorage.cs index 3917486..d7c319b 100644 --- a/IceCreamShop/IceCreamShopListImplement/Implements/MessageInfoStorage.cs +++ b/IceCreamShop/IceCreamShopListImplement/Implements/MessageInfoStorage.cs @@ -1,12 +1,13 @@ using IceCreamShopContracts.BindingModels; using IceCreamShopContracts.SearchModels; using IceCreamShopContracts.ViewModels; +using IceCreamShopContracts.StoragesContracts; using IceCreamShopListImplement.Models; namespace IceCreamShopListImplement.Implements { - public class MessageInfoStorage - { + public class MessageInfoStorage : IMessageInfoStorage + { private readonly DataListSingleton _source; public MessageInfoStorage() { diff --git a/IceCreamShop/IceCreamShopListImplement/ListImplementationExtension.cs b/IceCreamShop/IceCreamShopListImplement/ListImplementationExtension.cs new file mode 100644 index 0000000..a81df9a --- /dev/null +++ b/IceCreamShop/IceCreamShopListImplement/ListImplementationExtension.cs @@ -0,0 +1,23 @@ +using IceCreamShopContracts.DI; +using IceCreamShopContracts.StoragesContracts; +using IceCreamShopListImplement.Implements; + +namespace IceCreamShopListImplement +{ + 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/IceCreamShop/IceCreamShopListImplement/Models/MessageInfo.cs b/IceCreamShop/IceCreamShopListImplement/Models/MessageInfo.cs index 240ac3e..b8dc980 100644 --- a/IceCreamShop/IceCreamShopListImplement/Models/MessageInfo.cs +++ b/IceCreamShop/IceCreamShopListImplement/Models/MessageInfo.cs @@ -45,5 +45,6 @@ namespace IceCreamShopListImplement.Models DateDelivery = DateDelivery, }; - } + public int Id => throw new NotImplementedException(); + } } diff --git a/IceCreamShop/ImplementationExtensions/IceCreamShopContracts.dll b/IceCreamShop/ImplementationExtensions/IceCreamShopContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..5e2b943aecb6e9bc35f3a7bbc9ae1a07de193735 GIT binary patch literal 31744 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 literal 0 HcmV?d00001 diff --git a/IceCreamShop/ImplementationExtensions/IceCreamShopDataModels.dll b/IceCreamShop/ImplementationExtensions/IceCreamShopDataModels.dll new file mode 100644 index 0000000000000000000000000000000000000000..749fa9084aaa2d35e8179842440d2be4554e64eb GIT binary patch literal 6144 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 literal 0 HcmV?d00001 diff --git a/IceCreamShop/ImplementationExtensions/IceCreamShopListImplement.dll b/IceCreamShop/ImplementationExtensions/IceCreamShopListImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..8db3c1656441495d99876b048ac1af46678f82fc GIT binary patch literal 26112 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 E7nT9ADF6Tf literal 0 HcmV?d00001