From e0056206ecd7de36b1cc79ac4aa0515e1d077bc5 Mon Sep 17 00:00:00 2001 From: malimova Date: Tue, 4 Jun 2024 08:48:13 +0400 Subject: [PATCH 1/2] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=D1=87=D1=82=D0=B8=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D0=B5=D1=86=20=D0=BB=D0=B0=D0=B18.=20=D0=A1=D0=BA=D0=BE=D0=BF?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=D0=B0=20=D0=B2=D1=81=D1=91?= =?UTF-8?q?=20=D1=81=D0=BE=20=D1=81=D0=B2=D0=BE=D0=B5=D0=B9=20=D0=B2=D0=B5?= =?UTF-8?q?=D0=BA=D0=B8=20Lab8=5Fbase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConfectioneryBusinessLogic/BackUpLogic.cs | 102 +++++ .../Attributes/ColumnAttribute.cs | 30 ++ .../Attributes/GridViewAutoSize.cs | 27 ++ .../BindingModels/BackUpSaveBinidngModel.cs | 13 + .../BindingModels/MessageInfoBindingModel.cs | 1 + .../BusinessLogicsContracts/IBackUpLogic.cs | 14 + .../DI/DependencyManager.cs | 66 +++ .../DI/IDependencyContainer.cs | 40 ++ .../DI/IImplementationExtension.cs | 17 + .../DI/ServiceDependencyContainer.cs | 62 +++ .../DI/ServiceProviderLoader.cs | 55 +++ .../DI/UnityDependencyContainer.cs | 42 ++ .../StoragesContracts/IBackUpInfo.cs | 15 + .../ViewModels/ClientViewModel.cs | 10 +- .../ViewModels/ComponentViewModel.cs | 18 +- .../ViewModels/ImplementerViewModel.cs | 10 +- .../ViewModels/MessageInfoViewModel.cs | 14 +- .../ViewModels/OrderViewModel.cs | 23 +- .../ViewModels/PastryViewModel.cs | 21 +- .../IMessageInfoModel.cs | 2 +- .../BackUpInfo.cs | 32 ++ .../ConfectioneryDatabaseImplement/Client.cs | 7 +- .../Component.cs | 99 +++-- .../ConfectioneryDatabaseImplement.csproj | 4 + .../DatabaseImplementationExtension.cs | 27 ++ .../Implementer.cs | 11 +- .../MessageInfo.cs | 14 +- .../ConfectioneryDatabaseImplement/Order.cs | 41 +- .../ConfectioneryDatabaseImplement/Pastry.cs | 168 +++---- .../ConfectioneryFileImplement/BackUpInfo.cs | 44 ++ .../ConfectioneryFileImplement/Client.cs | 125 +++--- .../ConfectioneryFileImplement/Component.cs | 107 ++--- .../ConfectioneryFileImplement.csproj | 4 + .../ImplementationExtension.cs | 27 ++ .../ConfectioneryFileImplement/Implementer.cs | 21 +- .../ConfectioneryFileImplement/MessageInfo.cs | 15 +- .../ConfectioneryFileImplement/Order.cs | 27 +- .../ConfectioneryFileImplement/Pastry.cs | 163 +++---- .../ConfectioneryListImplement/BackUpInfo.cs | 22 + .../ConfectioneryListImplement.csproj | 4 + .../ImplementationExtension.cs | 27 ++ .../ConfectioneryListImplement/MessageInfo.cs | 1 + .../DataGridViewExtension.cs | 51 +++ .../ConfectioneryView/FormClients.cs | 18 +- .../ConfectioneryView/FormComponents.cs | 174 ++++---- .../ConfectioneryView/FormImplementers.cs | 30 +- Confectionery/ConfectioneryView/FormMail.cs | 10 +- .../ConfectioneryView/FormMain.Designer.cs | 23 +- Confectionery/ConfectioneryView/FormMain.cs | 102 ++--- Confectionery/ConfectioneryView/FormPastry.cs | 419 +++++++++--------- .../ConfectioneryView/FormPastrys.cs | 173 ++++---- Confectionery/ConfectioneryView/Program.cs | 85 ++-- 52 files changed, 1710 insertions(+), 947 deletions(-) create mode 100644 Confectionery/ConfectioneryBusinessLogic/BackUpLogic.cs create mode 100644 Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs create mode 100644 Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs create mode 100644 Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBinidngModel.cs create mode 100644 Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/DependencyManager.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/ServiceDependencyContainer.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs create mode 100644 Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 Confectionery/ConfectioneryDatabaseImplement/BackUpInfo.cs create mode 100644 Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryFileImplement/BackUpInfo.cs create mode 100644 Confectionery/ConfectioneryFileImplement/ImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryListImplement/BackUpInfo.cs create mode 100644 Confectionery/ConfectioneryListImplement/ImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryView/DataGridViewExtension.cs diff --git a/Confectionery/ConfectioneryBusinessLogic/BackUpLogic.cs b/Confectionery/ConfectioneryBusinessLogic/BackUpLogic.cs new file mode 100644 index 0000000..548cda6 --- /dev/null +++ b/Confectionery/ConfectioneryBusinessLogic/BackUpLogic.cs @@ -0,0 +1,102 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryDataModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.IO.Compression; +using System.Reflection; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Threading.Tasks; + +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); + } + } +} \ No newline at end of file diff --git a/Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs b/Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..20f005c --- /dev/null +++ b/Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.Attributes +{ + [AttributeUsage(AttributeTargets.Property)] + public class ColumnAttribute : Attribute + { + public ColumnAttribute(string title = "", bool visible = true, int width = 0, GridViewAutoSize gridViewAutoSize = GridViewAutoSize.None, bool isUseAutoSize = false) + { + Title = title; + Visible = visible; + Width = width; + GridViewAutoSize = gridViewAutoSize; + IsUseAutoSize = isUseAutoSize; + } + public string Title { get; private set; } + + public bool Visible { get; private set; } + + public int Width { get; private set; } + + public GridViewAutoSize GridViewAutoSize { get; private set; } + + public bool IsUseAutoSize { get; private set; } + } +} diff --git a/Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs b/Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..5066c83 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + + None = 1, + + ColumnHeader = 2, + + AllCellsExceptHeader = 4, + + AllCells = 6, + + DisplayedCellsExceptHeader = 8, + + DisplayedCells = 10, + + Fill = 16 + } +} diff --git a/Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBinidngModel.cs b/Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBinidngModel.cs new file mode 100644 index 0000000..d9c4f01 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBinidngModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.BindingModels +{ + public class BackUpSaveBinidngModel + { + public string FolderName { get; set; } = string.Empty; + } +} diff --git a/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs b/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs index e101807..611b00a 100644 --- a/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs +++ b/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs @@ -9,6 +9,7 @@ namespace ConfectioneryContracts.BindingModels { public class MessageInfoBindingModel : IMessageInfoModel { + public int Id => throw new NotImplementedException(); public string MessageId { get; set; } = string.Empty; public int? ClientId { get; set; } public string SenderName { get; set; } = string.Empty; diff --git a/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs b/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..d037887 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ConfectioneryContracts.BindingModels; + +namespace ConfectioneryContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBinidngModel model); + } +} diff --git a/Confectionery/ConfectioneryContracts/DI/DependencyManager.cs b/Confectionery/ConfectioneryContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..5ad4b3a --- /dev/null +++ b/Confectionery/ConfectioneryContracts/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 ConfectioneryContracts.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/Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs b/Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..3570776 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.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/Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs b/Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..5a82ed5 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.DI +{ + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} diff --git a/Confectionery/ConfectioneryContracts/DI/ServiceDependencyContainer.cs b/Confectionery/ConfectioneryContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..eef5984 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/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 ConfectioneryContracts.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/Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs b/Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..4b87754 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.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/Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs b/Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..91636b4 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unity.Microsoft.Logging; +using Unity; +using Microsoft.Extensions.Logging; + +namespace ConfectioneryContracts.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 U : class, T where T : class + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + } + + public void RegisterType(bool isSingle) where T : class + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + } + + public T Resolve() + { + return _container.Resolve(); + } + } +} diff --git a/Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs b/Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..3a66c37 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} diff --git a/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs index 7b837cb..14fcb57 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs @@ -1,4 +1,5 @@ -using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; +using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,12 +11,13 @@ namespace ConfectioneryContracts.ViewModels { public class ClientViewModel : IClientModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО клиента")] + [Column(title: "ФИО клиента", width: 150)] public string ClientFIO { get; set; } = string.Empty; - [DisplayName("Логин (эл. почта)")] + [Column(title: "Логин (эл. почта)", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Email { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column(title: "Пароль", width: 150)] public string Password { get; set; } = string.Empty; } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs index 7ef4f36..5d0d131 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs @@ -1,4 +1,5 @@ using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; using System; using System.Collections.Generic; using System.ComponentModel; @@ -8,12 +9,13 @@ using System.Threading.Tasks; namespace ConfectioneryContracts.ViewModels { - public class ComponentViewModel : IComponentModel - { - public int Id { get; set; } - [DisplayName("Название компонента")] - public string ComponentName { get; set; } = string.Empty; - [DisplayName("Цена")] - public double Cost { get; set; } - } + public class ComponentViewModel : IComponentModel + { + [Column(visible: false)] + public int Id { get; set; } + [Column(title: "Название компонента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string ComponentName { get; set; } = string.Empty; + [Column(title: "Цена", width: 150)] + public double Cost { get; set; } + } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs index 7427339..cc178f7 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs @@ -1,4 +1,5 @@ using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,18 +11,19 @@ namespace ConfectioneryContracts.ViewModels { public class ImplementerViewModel : IImplementerModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО исполнителя")] + [Column(title: "ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column(title: "Пароль", width: 100)] public string Password { get; set; } = string.Empty; - [DisplayName("Стаж работы")] + [Column(title: "Стаж работы", width: 60)] public int WorkExperience { get; set; } - [DisplayName("Квалификация")] + [Column(title: "Квалификация", width: 60)] public int Qualification { get; set; } } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs index 6f8e090..d7f41f6 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs @@ -1,4 +1,5 @@ using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,20 +11,23 @@ namespace ConfectioneryContracts.ViewModels { public class MessageInfoViewModel : IMessageInfoModel { + [Column(visible: false)] + public int Id { get; set; } + [Column(visible: false)] public string MessageId { get; set; } = string.Empty; - + [Column(visible: false)] public int? ClientId { get; set; } - [DisplayName("Отправитель")] + [Column(title: "Отправитель", width: 150)] public string SenderName { get; set; } = string.Empty; - [DisplayName("Дата письма")] + [Column(title: "Дата письма", width: 120)] public DateTime DateDelivery { get; set; } - [DisplayName("Заголовок")] + [Column(title: "Заголовок", width: 120)] public string Subject { get; set; } = string.Empty; - [DisplayName("Текст")] + [Column(title: "Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Body { get; set; } = string.Empty; } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs index e1dbe9f..7085703 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs @@ -1,5 +1,6 @@ using ConfectioneryDataModels.Enums; using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; using System; using System.Collections.Generic; using System.ComponentModel; @@ -11,28 +12,32 @@ namespace ConfectioneryContracts.ViewModels { public class OrderViewModel : IOrderModel { - [DisplayName("Номер")] + [Column(title: "Номер", width: 90)] public int Id { get; set; } + [Column(visible: false)] public int ClientId { get; set; } - [DisplayName("ФИО клиента")] + [Column(title: "ФИО клиента", width: 190)] public string ClientFIO { get; set; } = string.Empty; + [Column(visible: false)] public string ClientEmail { get; set; } = string.Empty; + [Column(visible: false)] public int? ImplementerId { get; set; } - [DisplayName("Исполнитель")] + [Column(title: "Исполнитель", width: 150)] public string? ImplementerFIO { get; set; } = null; + [Column(visible: false)] public int PastryId { get; set; } - [DisplayName("Изделие")] + [Column(title: "Изделие", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string PastryName { get; set; } = string.Empty; - [DisplayName("Количество")] + [Column(title: "Количество", width: 100)] public int Count { get; set; } - [DisplayName("Сумма")] + [Column(title: "Сумма", width: 120)] public double Sum { get; set; } - [DisplayName("Статус")] + [Column(title: "Статус", width: 70)] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; - [DisplayName("Дата создания")] + [Column(title: "Дата создания", width: 120)] public DateTime DateCreate { get; set; } = DateTime.Now; - [DisplayName("Дата выполнения")] + [Column(title: "Дата выполнения", width: 120)] public DateTime? DateImplement { get; set; } } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs index 15257b0..841d3e5 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs @@ -1,4 +1,5 @@ using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; using System; using System.Collections.Generic; using System.ComponentModel; @@ -8,13 +9,15 @@ using System.Threading.Tasks; namespace ConfectioneryContracts.ViewModels { - public class PastryViewModel : IPastryModel - { - public int Id { get; set; } - [DisplayName("Название изделия")] - public string PastryName { get; set; } = string.Empty; - [DisplayName("Цена")] - public double Price { get; set; } - public Dictionary PastryComponents { get; set; } = new(); - } + public class PastryViewModel : IPastryModel + { + [Column(visible: false)] + public int Id { get; set; } + [Column(title: "Название изделия", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string PastryName { get; set; } = string.Empty; + [Column(title: "Цена", width: 70)] + public double Price { get; set; } + [Column(visible: false)] + public Dictionary PastryComponents { get; set; } = new(); + } } diff --git a/Confectionery/ConfectioneryDataModels/IMessageInfoModel.cs b/Confectionery/ConfectioneryDataModels/IMessageInfoModel.cs index ac8025d..01536e5 100644 --- a/Confectionery/ConfectioneryDataModels/IMessageInfoModel.cs +++ b/Confectionery/ConfectioneryDataModels/IMessageInfoModel.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace ConfectioneryDataModels.Models { - public interface IMessageInfoModel + public interface IMessageInfoModel : IId { string MessageId { get; } int? ClientId { get; } diff --git a/Confectionery/ConfectioneryDatabaseImplement/BackUpInfo.cs b/Confectionery/ConfectioneryDatabaseImplement/BackUpInfo.cs new file mode 100644 index 0000000..8285fba --- /dev/null +++ b/Confectionery/ConfectioneryDatabaseImplement/BackUpInfo.cs @@ -0,0 +1,32 @@ +using ConfectioneryContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryDatabaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new ConfectioneryDatabase(); + 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/Confectionery/ConfectioneryDatabaseImplement/Client.cs b/Confectionery/ConfectioneryDatabaseImplement/Client.cs index f5eda43..9ec9f80 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Client.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Client.cs @@ -8,17 +8,22 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.Serialization; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Client : IClientModel { + [DataMember] public int Id { get; private set; } - + [DataMember] [Required] public string ClientFIO { get; set; } = string.Empty; + [DataMember] [Required] public string Email { get; set; } = string.Empty; + [DataMember] [Required] public string Password { get; set; } = string.Empty; diff --git a/Confectionery/ConfectioneryDatabaseImplement/Component.cs b/Confectionery/ConfectioneryDatabaseImplement/Component.cs index a350c35..6602010 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Component.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Component.cs @@ -3,54 +3,59 @@ using ConfectioneryContracts.ViewModels; using ConfectioneryDataModels.Models; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Runtime.Serialization; namespace ConfectioneryDatabaseImplement.Models { - 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")] - public virtual List PastryComponents { get; set; } = new(); - public static Component? Create(ComponentBindingModel model) - { - if (model == null) - { - return null; - } - return new Component() - { - Id = model.Id, - ComponentName = model.ComponentName, - Cost = model.Cost - }; - } - public static Component Create(ComponentViewModel model) - { - return new Component - { - Id = model.Id, - ComponentName = model.ComponentName, - Cost = model.Cost - }; - } - public void Update(ComponentBindingModel model) - { - if (model == null) - { - return; - } - ComponentName = model.ComponentName; - Cost = model.Cost; - } - public ComponentViewModel GetViewModel => new() - { - Id = Id, - ComponentName = ComponentName, - Cost = Cost - }; - } + [DataContract] + public class Component : IComponentModel + { + [DataMember] + public int Id { get; private set; } + [DataMember] + [Required] + public string ComponentName { get; private set; } = string.Empty; + [DataMember] + [Required] + public double Cost { get; set; } + [ForeignKey("ComponentId")] + public virtual List PastryComponents { get; set; } = new(); + public static Component? Create(ComponentBindingModel model) + { + if (model == null) + { + return null; + } + return new Component() + { + Id = model.Id, + ComponentName = model.ComponentName, + Cost = model.Cost + }; + } + public static Component Create(ComponentViewModel model) + { + return new Component + { + Id = model.Id, + ComponentName = model.ComponentName, + Cost = model.Cost + }; + } + public void Update(ComponentBindingModel model) + { + if (model == null) + { + return; + } + ComponentName = model.ComponentName; + Cost = model.Cost; + } + public ComponentViewModel GetViewModel => new() + { + Id = Id, + ComponentName = ComponentName, + Cost = Cost + }; + } } \ No newline at end of file diff --git a/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj b/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj index 428d10d..1d9f5f7 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj +++ b/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj @@ -20,4 +20,8 @@ + + + + diff --git a/Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs b/Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs new file mode 100644 index 0000000..5fb0f57 --- /dev/null +++ b/Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs @@ -0,0 +1,27 @@ +using ConfectioneryContracts.DI; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryDatabaseImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryDatabaseImplement +{ + 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/Confectionery/ConfectioneryDatabaseImplement/Implementer.cs b/Confectionery/ConfectioneryDatabaseImplement/Implementer.cs index 7282a3e..1b16f8f 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Implementer.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Implementer.cs @@ -8,22 +8,25 @@ using ConfectioneryContracts.ViewModels; using ConfectioneryDataModels.Models; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Implementer : IImplementerModel { + [DataMember] public int Id { get; set; } - + [DataMember] [Required] public string ImplementerFIO { get; set; } = string.Empty; - + [DataMember] [Required] public string Password { get; set; } = string.Empty; - + [DataMember] [Required] public int WorkExperience { get; set; } - + [DataMember] [Required] public int Qualification { get; set; } diff --git a/Confectionery/ConfectioneryDatabaseImplement/MessageInfo.cs b/Confectionery/ConfectioneryDatabaseImplement/MessageInfo.cs index 926aa49..bb22a39 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/MessageInfo.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/MessageInfo.cs @@ -8,28 +8,32 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.Serialization; namespace ConfectioneryDatabaseImplement.Models { public class MessageInfo : IMessageInfoModel { + [NotMapped] + public int Id { get; private set; } + [DataMember] [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public string MessageId { get; set; } = string.Empty; - + [DataMember] public int? ClientId { get; set; } public virtual Client? Client { get; set; } - + [DataMember] [Required] public string SenderName { get; set; } = string.Empty; - + [DataMember] [Required] public DateTime DateDelivery { get; set; } - + [DataMember] [Required] public string Subject { get; set; } = string.Empty; - + [DataMember] [Required] public string Body { get; set; } = string.Empty; diff --git a/Confectionery/ConfectioneryDatabaseImplement/Order.cs b/Confectionery/ConfectioneryDatabaseImplement/Order.cs index 9f70fa3..16355d2 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Order.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Order.cs @@ -6,39 +6,42 @@ 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 ConfectioneryDatabaseImplement.Models { + [DataContract] public class Order : IOrderModel { - public int Id { get; private set; } + [DataMember] + public int Id { get; set; } + [DataMember] [Required] - public int ClientId { get; private set; } - - public virtual Client Client { get; private set; } = new(); - + public int PastryId { get; set; } + [DataMember] [Required] - public int PastryId { get; private set; } - - public virtual Pastry Pastry { get; set; } = new(); + public int ClientId { get; set; } + [DataMember] public int? ImplementerId { get; private set; } - public virtual Implementer? Implementer { get; set; } = new(); - + [DataMember] [Required] - public int Count { get; private set; } - + public int Count { get; set; } + [DataMember] [Required] - public double Sum { get; private set; } - + public double Sum { get; set; } + [DataMember] [Required] - public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; - + public OrderStatus Status { get; set; } + [DataMember] [Required] - public DateTime DateCreate { get; private set; } = DateTime.Now; - - public DateTime? DateImplement { get; private set; } + public DateTime DateCreate { get; set; } + [DataMember] + public DateTime? DateImplement { get; set; } + public virtual Pastry Pastry { get; set; } + public virtual Client Client { get; set; } + public virtual Implementer? Implementer { get; set; } public static Order Create(ConfectioneryDatabase context, OrderBindingModel model) { diff --git a/Confectionery/ConfectioneryDatabaseImplement/Pastry.cs b/Confectionery/ConfectioneryDatabaseImplement/Pastry.cs index ea42b37..1f56e28 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Pastry.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Pastry.cs @@ -8,89 +8,95 @@ using ConfectioneryContracts.ViewModels; using ConfectioneryDataModels.Models; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Runtime.Serialization; namespace ConfectioneryDatabaseImplement.Models { - public class Pastry : IPastryModel - { - public int Id { get; set; } - [Required] - public string PastryName { get; set; } = string.Empty; - [Required] - public double Price { get; set; } - private Dictionary? _pastryComponents = null; - [NotMapped] - public Dictionary PastryComponents - { - get - { - if (_pastryComponents == null) - { - _pastryComponents = Components - .ToDictionary(recPC => recPC.ComponentId, recPC => - (recPC.Component as IComponentModel, recPC.Count)); - } - return _pastryComponents; - } - } - [ForeignKey("PastryId")] - public virtual List Components { get; set; } = new(); - [ForeignKey("PastryId")] - public virtual List Orders { get; set; } = new(); - public static Pastry Create(ConfectioneryDatabase context, PastryBindingModel model) - { - return new Pastry() - { - Id = model.Id, - PastryName = model.PastryName, - Price = model.Price, - Components = model.PastryComponents.Select(x => new PastryComponent - { - Component = context.Components.First(y => y.Id == x.Key), - Count = x.Value.Item2 - }).ToList() - }; - } - public void Update(PastryBindingModel model) - { - PastryName = model.PastryName; - Price = model.Price; - } - public PastryViewModel GetViewModel => new() - { - Id = Id, - PastryName = PastryName, - Price = Price, - PastryComponents = PastryComponents - }; - public void UpdateComponents(ConfectioneryDatabase context, PastryBindingModel model) - { - var pastryComponents = context.PastryComponents.Where(rec => rec.PastryId == model.Id).ToList(); - if (pastryComponents != null && pastryComponents.Count > 0) - { // удалили те, которых нет в модели - context.PastryComponents.RemoveRange(pastryComponents.Where(rec => !model.PastryComponents.ContainsKey(rec.ComponentId))); - context.SaveChanges(); - // обновили количество у существующих записей - foreach (var updateComponent in pastryComponents) - { - updateComponent.Count = model.PastryComponents[updateComponent.ComponentId].Item2; - model.PastryComponents.Remove(updateComponent.ComponentId); - } - context.SaveChanges(); - } - var pastry = context.Pastrys.First(x => x.Id == Id); - foreach (var pc in model.PastryComponents) - { - context.PastryComponents.Add(new PastryComponent - { - Pastry = pastry, - Component = context.Components.First(x => x.Id == pc.Key), - Count = pc.Value.Item2 - }); - context.SaveChanges(); - } - _pastryComponents = null; - } - } + [DataContract] + public class Pastry : IPastryModel + { + [DataMember] + public int Id { get; set; } + [DataMember] + [Required] + public string PastryName { get; set; } = string.Empty; + [DataMember] + [Required] + public double Price { get; set; } + private Dictionary? _pastryComponents = null; + [DataMember] + [NotMapped] + public Dictionary PastryComponents + { + get + { + if (_pastryComponents == null) + { + _pastryComponents = Components + .ToDictionary(recPC => recPC.ComponentId, recPC => + (recPC.Component as IComponentModel, recPC.Count)); + } + return _pastryComponents; + } + } + [ForeignKey("PastryId")] + public virtual List Components { get; set; } = new(); + [ForeignKey("PastryId")] + public virtual List Orders { get; set; } = new(); + public static Pastry Create(ConfectioneryDatabase context, PastryBindingModel model) + { + return new Pastry() + { + Id = model.Id, + PastryName = model.PastryName, + Price = model.Price, + Components = model.PastryComponents.Select(x => new PastryComponent + { + Component = context.Components.First(y => y.Id == x.Key), + Count = x.Value.Item2 + }).ToList() + }; + } + public void Update(PastryBindingModel model) + { + PastryName = model.PastryName; + Price = model.Price; + } + public PastryViewModel GetViewModel => new() + { + Id = Id, + PastryName = PastryName, + Price = Price, + PastryComponents = PastryComponents + }; + public void UpdateComponents(ConfectioneryDatabase context, PastryBindingModel model) + { + var pastryComponents = context.PastryComponents.Where(rec => rec.PastryId == model.Id).ToList(); + if (pastryComponents != null && pastryComponents.Count > 0) + { // удалили те, которых нет в модели + context.PastryComponents.RemoveRange(pastryComponents.Where(rec => !model.PastryComponents.ContainsKey(rec.ComponentId))); + context.SaveChanges(); + // обновили количество у существующих записей + foreach (var updateComponent in pastryComponents) + { + updateComponent.Count = model.PastryComponents[updateComponent.ComponentId].Item2; + model.PastryComponents.Remove(updateComponent.ComponentId); + } + context.SaveChanges(); + } + var pastry = context.Pastrys.First(x => x.Id == Id); + foreach (var pc in model.PastryComponents) + { + context.PastryComponents.Add(new PastryComponent + { + Pastry = pastry, + Component = context.Components.First(x => x.Id == pc.Key), + Count = pc.Value.Item2 + }); + context.SaveChanges(); + } + _pastryComponents = null; + } + } } diff --git a/Confectionery/ConfectioneryFileImplement/BackUpInfo.cs b/Confectionery/ConfectioneryFileImplement/BackUpInfo.cs new file mode 100644 index 0000000..cee3913 --- /dev/null +++ b/Confectionery/ConfectioneryFileImplement/BackUpInfo.cs @@ -0,0 +1,44 @@ +using ConfectioneryContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement +{ + public class BackUpInfo : IBackUpInfo + { + private readonly DataFileSingleton source; + private readonly PropertyInfo[] sourceProperties; + + public BackUpInfo() + { + source = DataFileSingleton.GetInstance(); + sourceProperties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); + } + + public List? GetList() where T : class, new() + { + var requredType = typeof(T); + return (List?)sourceProperties.FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == requredType) + ?.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/Confectionery/ConfectioneryFileImplement/Client.cs b/Confectionery/ConfectioneryFileImplement/Client.cs index c87c19f..0ab8629 100644 --- a/Confectionery/ConfectioneryFileImplement/Client.cs +++ b/Confectionery/ConfectioneryFileImplement/Client.cs @@ -4,73 +4,82 @@ using ConfectioneryDataModels.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 ConfectioneryFileImplement +namespace ConfectioneryFileImplement.Models { - public class Client : IClientModel - { - public int Id { get; set; } - public string ClientFIO { get; set; } = string.Empty; - public string Password { get; set; } = string.Empty; - public string Email { get; set; } = string.Empty; + [DataContract] + public class Client : IClientModel + { + [DataMember] + public int Id { get; private set; } - public static Client? Create(ClientBindingModel? model) - { - if (model == null) - { - return null; - } - return new Client() - { - Id = model.Id, - ClientFIO = model.ClientFIO, - Password = model.Password, - Email = model.Email - }; - } + [DataMember] + public string ClientFIO { get; private set; } = string.Empty; - public static Client? Create(XElement element) - { - if (element == null) - { - return null; - } - return new Client() - { - Id = Convert.ToInt32(element.Attribute("Id")!.Value), - ClientFIO = element.Attribute("ClientFIO")!.Value, - Password = element.Attribute("Password")!.Value, - Email = element.Attribute("Email")!.Value - }; - } + [DataMember] + public string Email { get; private set; } = string.Empty; - public void Update(ClientBindingModel? model) - { - if (model == null) - { - return; - } - ClientFIO = model.ClientFIO; - Password = model.Password; - Email = model.Email; - } + [DataMember] + public string Password { get; private set; } = string.Empty; - public ClientViewModel GetViewModel => new() - { - Id = Id, - ClientFIO = ClientFIO, - Password = Password, - Email = Email - }; + public static Client? Create(ClientBindingModel? model) + { + if (model == null) + { + return null; + } + return new Client() + { + Id = model.Id, + ClientFIO = model.ClientFIO, + Password = model.Password, + Email = model.Email + }; + } - public XElement GetXElement => new("Client", - new XAttribute("Id", Id), - new XElement("ClientFIO", ClientFIO), - new XElement("Password", Password), - new XElement("Email", Email)); - } + public static Client? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Client() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ClientFIO = element.Attribute("ClientFIO")!.Value, + Password = element.Attribute("Password")!.Value, + Email = element.Attribute("Email")!.Value + }; + } + + public void Update(ClientBindingModel? model) + { + if (model == null) + { + return; + } + ClientFIO = model.ClientFIO; + Password = model.Password; + Email = model.Email; + } + + public ClientViewModel GetViewModel => new() + { + Id = Id, + ClientFIO = ClientFIO, + Password = Password, + Email = Email + }; + + public XElement GetXElement => new("Client", + new XAttribute("Id", Id), + new XElement("ClientFIO", ClientFIO), + new XElement("Password", Password), + new XElement("Email", Email)); + } } diff --git a/Confectionery/ConfectioneryFileImplement/Component.cs b/Confectionery/ConfectioneryFileImplement/Component.cs index 38ab4a0..cbeea94 100644 --- a/Confectionery/ConfectioneryFileImplement/Component.cs +++ b/Confectionery/ConfectioneryFileImplement/Component.cs @@ -1,59 +1,64 @@ using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.ViewModels; using ConfectioneryDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace ConfectioneryFileImplement.Models { - 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) - { - if (model == null) - { - return null; - } - return new Component() - { - Id = model.Id, - ComponentName = model.ComponentName, - Cost = model.Cost - }; - } - public static Component? Create(XElement element) - { - if (element == null) - { - return null; - } - return new Component() - { - Id = Convert.ToInt32(element.Attribute("Id")!.Value), - ComponentName = element.Element("ComponentName")!.Value, - Cost = Convert.ToDouble(element.Element("Cost")!.Value) - }; - } - public void Update(ComponentBindingModel model) - { - if (model == null) - { - return; - } - ComponentName = model.ComponentName; - Cost = model.Cost; - } - public ComponentViewModel GetViewModel => new() - { - Id = Id, - ComponentName = ComponentName, - Cost = Cost - }; - public XElement GetXElement => new("Component", - new XAttribute("Id", Id), - new XElement("ComponentName", ComponentName), - new XElement("Cost", Cost.ToString())); - } + [DataContract] + public class Component : IComponentModel + { + [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) + { + return null; + } + return new Component() + { + Id = model.Id, + ComponentName = model.ComponentName, + Cost = model.Cost + }; + } + public static Component? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Component() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ComponentName = element.Element("ComponentName")!.Value, + Cost = Convert.ToDouble(element.Element("Cost")!.Value) + }; + } + public void Update(ComponentBindingModel model) + { + if (model == null) + { + return; + } + ComponentName = model.ComponentName; + Cost = model.Cost; + } + public ComponentViewModel GetViewModel => new() + { + Id = Id, + ComponentName = ComponentName, + Cost = Cost + }; + public XElement GetXElement => new("Component", + new XAttribute("Id", Id), + new XElement("ComponentName", ComponentName), + new XElement("Cost", Cost.ToString())); + } } diff --git a/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj b/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj index 965df58..e350124 100644 --- a/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj +++ b/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj @@ -16,4 +16,8 @@ + + + + diff --git a/Confectionery/ConfectioneryFileImplement/ImplementationExtension.cs b/Confectionery/ConfectioneryFileImplement/ImplementationExtension.cs new file mode 100644 index 0000000..4c1f970 --- /dev/null +++ b/Confectionery/ConfectioneryFileImplement/ImplementationExtension.cs @@ -0,0 +1,27 @@ +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryDatabaseImplement.Implements; +using ConfectioneryContracts.DI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement +{ + public class ImplementationExtension + { + 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/Confectionery/ConfectioneryFileImplement/Implementer.cs b/Confectionery/ConfectioneryFileImplement/Implementer.cs index 586579a..3c34e3f 100644 --- a/Confectionery/ConfectioneryFileImplement/Implementer.cs +++ b/Confectionery/ConfectioneryFileImplement/Implementer.cs @@ -4,23 +4,26 @@ using ConfectioneryDataModels.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 ConfectioneryFileImplement.Models { + [DataContract] public class Implementer : IImplementerModel { - public int Id { get; private set; } - - public string ImplementerFIO { get; private set; } = string.Empty; - - public string Password { get; private set; } = string.Empty; - - public int WorkExperience { get; private set; } - - public int Qualification { get; private set; } + [DataMember] + public int Id { get; set; } + [DataMember] + public string ImplementerFIO { get; set; } = string.Empty; + [DataMember] + public string Password { get; set; } = string.Empty; + [DataMember] + public int WorkExperience { get; set; } + [DataMember] + public int Qualification { get; set; } public static Implementer? Create(XElement element) { diff --git a/Confectionery/ConfectioneryFileImplement/MessageInfo.cs b/Confectionery/ConfectioneryFileImplement/MessageInfo.cs index 6889771..ac678c5 100644 --- a/Confectionery/ConfectioneryFileImplement/MessageInfo.cs +++ b/Confectionery/ConfectioneryFileImplement/MessageInfo.cs @@ -4,24 +4,29 @@ using ConfectioneryDataModels.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 ConfectioneryFileImplement.Models { + [DataContract] public class MessageInfo : IMessageInfoModel { + [DataMember] + public int Id { get; private set; } + [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) diff --git a/Confectionery/ConfectioneryFileImplement/Order.cs b/Confectionery/ConfectioneryFileImplement/Order.cs index e7e242f..85f350d 100644 --- a/Confectionery/ConfectioneryFileImplement/Order.cs +++ b/Confectionery/ConfectioneryFileImplement/Order.cs @@ -3,19 +3,38 @@ using ConfectioneryDataModels.Models; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.ViewModels; using System.Xml.Linq; +using System.Runtime.Serialization; namespace ConfectioneryFileImplement.Models { + [DataContract] public class Order : IOrderModel { + [DataMember] public int Id { get; private set; } - public int ClientId { get; private set; } - public int? ImplementerId { get; set; } + + [DataMember] public int PastryId { get; private set; } + + [DataMember] + public int ClientId { get; private set; } + + [DataMember] + public int? ImplementerId { get; private set; } + + [DataMember] public int Count { get; private set; } + + [DataMember] public double Sum { get; private set; } - public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; - public DateTime DateCreate { get; private set; } = DateTime.Now; + + [DataMember] + public OrderStatus Status { get; private set; } + + [DataMember] + public DateTime DateCreate { get; private set; } + + [DataMember] public DateTime? DateImplement { get; private set; } public static Order? Create(OrderBindingModel? model) diff --git a/Confectionery/ConfectioneryFileImplement/Pastry.cs b/Confectionery/ConfectioneryFileImplement/Pastry.cs index 7611b91..9256813 100644 --- a/Confectionery/ConfectioneryFileImplement/Pastry.cs +++ b/Confectionery/ConfectioneryFileImplement/Pastry.cs @@ -7,90 +7,95 @@ using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.ViewModels; using ConfectioneryDataModels.Models; using System.Xml.Linq; +using System.Runtime.Serialization; namespace ConfectioneryFileImplement.Models { - public class Pastry : IPastryModel - { - public int Id { get; private set; } - public string PastryName { get; private set; } = string.Empty; - public double Price { get; private set; } - public Dictionary Components { get; private set; } = new(); + [DataContract] + public class Pastry : IPastryModel + { + [DataMember] + public int Id { get; private set; } + [DataMember] + public string PastryName { get; private set; } = string.Empty; + [DataMember] + public double Price { get; private set; } + public Dictionary Components { get; private set; } = new(); - private Dictionary? _pastryComponents = null; - public Dictionary PastryComponents - { - get - { - if (_pastryComponents == null) - { - var source = DataFileSingleton.GetInstance(); - _pastryComponents = Components.ToDictionary(x => x.Key, y => - ((source.Components.FirstOrDefault(z => z.Id == y.Key) as IComponentModel)!, - y.Value)); - } - return _pastryComponents; - } - } - public static Pastry? Create(PastryBindingModel model) - { - if (model == null) - { - return null; - } - return new Pastry() - { - Id = model.Id, - PastryName = model.PastryName, - Price = model.Price, - Components = model.PastryComponents.ToDictionary(x => x.Key, x - => x.Value.Item2) - }; - } - public static Pastry? Create(XElement element) - { - if (element == null) - { - return null; - } - return new Pastry() - { - Id = Convert.ToInt32(element.Attribute("Id")!.Value), - PastryName = element.Element("PastryName")!.Value, - Price = Convert.ToDouble(element.Element("Price")!.Value), - Components = element.Element("PastryComponents")!.Elements("PastryComponent").ToDictionary - (x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)) - }; - } - public void Update(PastryBindingModel model) - { - if (model == null) - { - return; - } - PastryName = model.PastryName; - Price = model.Price; - Components = model.PastryComponents.ToDictionary(x => x.Key, x => x.Value.Item2); - _pastryComponents = null; - } - public PastryViewModel GetViewModel => new() - { - Id = Id, - PastryName = PastryName, - Price = Price, - PastryComponents = PastryComponents - }; - public XElement GetXElement => new("Pastry", - new XAttribute("Id", Id), - new XElement("PastryName", PastryName), - new XElement("Price", Price.ToString()), - new XElement("PastryComponents", Components.Select(x => - new XElement("PastryComponent", + private Dictionary? _pastryComponents = null; + public Dictionary PastryComponents + { + get + { + if (_pastryComponents == null) + { + var source = DataFileSingleton.GetInstance(); + _pastryComponents = Components.ToDictionary(x => x.Key, y => + ((source.Components.FirstOrDefault(z => z.Id == y.Key) as IComponentModel)!, + y.Value)); + } + return _pastryComponents; + } + } + public static Pastry? Create(PastryBindingModel model) + { + if (model == null) + { + return null; + } + return new Pastry() + { + Id = model.Id, + PastryName = model.PastryName, + Price = model.Price, + Components = model.PastryComponents.ToDictionary(x => x.Key, x + => x.Value.Item2) + }; + } + public static Pastry? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Pastry() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + PastryName = element.Element("PastryName")!.Value, + Price = Convert.ToDouble(element.Element("Price")!.Value), + Components = element.Element("PastryComponents")!.Elements("PastryComponent").ToDictionary + (x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)) + }; + } + public void Update(PastryBindingModel model) + { + if (model == null) + { + return; + } + PastryName = model.PastryName; + Price = model.Price; + Components = model.PastryComponents.ToDictionary(x => x.Key, x => x.Value.Item2); + _pastryComponents = null; + } + public PastryViewModel GetViewModel => new() + { + Id = Id, + PastryName = PastryName, + Price = Price, + PastryComponents = PastryComponents + }; + public XElement GetXElement => new("Pastry", + new XAttribute("Id", Id), + new XElement("PastryName", PastryName), + new XElement("Price", Price.ToString()), + new XElement("PastryComponents", Components.Select(x => + new XElement("PastryComponent", - new XElement("Key", x.Key), + new XElement("Key", x.Key), - new XElement("Value", x.Value))) + new XElement("Value", x.Value))) - .ToArray())); - } + .ToArray())); + } } diff --git a/Confectionery/ConfectioneryListImplement/BackUpInfo.cs b/Confectionery/ConfectioneryListImplement/BackUpInfo.cs new file mode 100644 index 0000000..fbfb17d --- /dev/null +++ b/Confectionery/ConfectioneryListImplement/BackUpInfo.cs @@ -0,0 +1,22 @@ +using ConfectioneryContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryListImplement.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/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj b/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj index 4473d7c..23e3c50 100644 --- a/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj +++ b/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj @@ -16,4 +16,8 @@ + + + + diff --git a/Confectionery/ConfectioneryListImplement/ImplementationExtension.cs b/Confectionery/ConfectioneryListImplement/ImplementationExtension.cs new file mode 100644 index 0000000..6e58c2d --- /dev/null +++ b/Confectionery/ConfectioneryListImplement/ImplementationExtension.cs @@ -0,0 +1,27 @@ +using ConfectioneryContracts.DI; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryListImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryListImplement +{ + public class ImplementationExtension : 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/Confectionery/ConfectioneryListImplement/MessageInfo.cs b/Confectionery/ConfectioneryListImplement/MessageInfo.cs index 81d7bad..6ff054b 100644 --- a/Confectionery/ConfectioneryListImplement/MessageInfo.cs +++ b/Confectionery/ConfectioneryListImplement/MessageInfo.cs @@ -11,6 +11,7 @@ namespace ConfectioneryListImplement.Models { public class MessageInfo : IMessageInfoModel { + public int Id => throw new NotImplementedException(); public string MessageId { get; private set; } = string.Empty; public int? ClientId { get; private set; } diff --git a/Confectionery/ConfectioneryView/DataGridViewExtension.cs b/Confectionery/ConfectioneryView/DataGridViewExtension.cs new file mode 100644 index 0000000..4099850 --- /dev/null +++ b/Confectionery/ConfectioneryView/DataGridViewExtension.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ConfectioneryContracts.Attributes; + +namespace ConfectioneryView +{ + 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/Confectionery/ConfectioneryView/FormClients.cs b/Confectionery/ConfectioneryView/FormClients.cs index a93ec53..e059d83 100644 --- a/Confectionery/ConfectioneryView/FormClients.cs +++ b/Confectionery/ConfectioneryView/FormClients.cs @@ -33,18 +33,12 @@ namespace ConfectioneryView private void LoadData() { - try - { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } - _logger.LogInformation("Загрузка списка клиентов"); - } - catch (Exception ex) + try + { + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка списка клиентов"); + } + catch (Exception ex) { _logger.LogError(ex, "Ошибка загрузки списка клиентов"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); diff --git a/Confectionery/ConfectioneryView/FormComponents.cs b/Confectionery/ConfectioneryView/FormComponents.cs index fb3ad31..05f66dd 100644 --- a/Confectionery/ConfectioneryView/FormComponents.cs +++ b/Confectionery/ConfectioneryView/FormComponents.cs @@ -1,5 +1,6 @@ using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -13,102 +14,89 @@ using System.Windows.Forms; namespace ConfectioneryView { - public partial class FormComponents : Form - { - private readonly ILogger _logger; - private readonly IComponentLogic _logic; - public FormComponents(ILogger logger, IComponentLogic logic) - { - InitializeComponent(); - _logger = logger; - _logic = logic; - } + public partial class FormComponents : Form + { + private readonly ILogger _logger; + private readonly IComponentLogic _logic; + public FormComponents(ILogger logger, IComponentLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + } - 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(); - } - } - } + private void buttonAdd_Click(object sender, EventArgs e) + { + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } - private void FormComponents_Load(object sender, EventArgs e) - { - LoadData(); - } - 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); - } - } + private void FormComponents_Load(object sender, EventArgs e) + { + LoadData(); + } + private void LoadData() + { + try + { + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка компонентов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки компонентов"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } - 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(); - } - } - } - } + private void buttonUpd_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + var form = DependencyManager.Instance.Resolve(); - private void buttonDel_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Удаление компонента"); - try - { - if (!_logic.Delete(new ComponentBindingModel - { - Id = id - })) - { - throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка удаления компонента"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } - } - private void buttonRef_Click(object sender, EventArgs e) - { - LoadData(); - } - } + private void buttonDel_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Удаление компонента"); + try + { + if (!_logic.Delete(new ComponentBindingModel + { + Id = id + })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления компонента"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + } + private void buttonRef_Click(object sender, EventArgs e) + { + LoadData(); + } + } } diff --git a/Confectionery/ConfectioneryView/FormImplementers.cs b/Confectionery/ConfectioneryView/FormImplementers.cs index be8dafb..f787819 100644 --- a/Confectionery/ConfectioneryView/FormImplementers.cs +++ b/Confectionery/ConfectioneryView/FormImplementers.cs @@ -1,5 +1,6 @@ using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -29,14 +30,7 @@ namespace ConfectioneryView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ImplementerFIO"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка исполнителей"); } catch (Exception ex) @@ -54,13 +48,10 @@ namespace ConfectioneryView 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(); } } @@ -68,14 +59,11 @@ namespace ConfectioneryView { 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/Confectionery/ConfectioneryView/FormMail.cs b/Confectionery/ConfectioneryView/FormMail.cs index 3def25c..e823f99 100644 --- a/Confectionery/ConfectioneryView/FormMail.cs +++ b/Confectionery/ConfectioneryView/FormMail.cs @@ -28,15 +28,7 @@ namespace ConfectioneryView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["MessageId"].Visible = false; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["Body"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка почтовых собщений"); } catch (Exception ex) diff --git a/Confectionery/ConfectioneryView/FormMain.Designer.cs b/Confectionery/ConfectioneryView/FormMain.Designer.cs index 7803f70..e1cdeb3 100644 --- a/Confectionery/ConfectioneryView/FormMain.Designer.cs +++ b/Confectionery/ConfectioneryView/FormMain.Designer.cs @@ -40,12 +40,13 @@ componentPastryToolStripMenuItem = new ToolStripMenuItem(); ordersListToolStripMenuItem = new ToolStripMenuItem(); startWorkToolStripMenuItem = new ToolStripMenuItem(); + mailToolStripMenuItem = new ToolStripMenuItem(); buttonCreateOrder = new Button(); buttonTakeOrderInWork = new Button(); buttonOrderReady = new Button(); buttonIssuedOrder = new Button(); buttonRef = new Button(); - mailToolStripMenuItem = new ToolStripMenuItem(); + createBackupToolStripMenuItem = new ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); menuStrip.SuspendLayout(); SuspendLayout(); @@ -63,7 +64,7 @@ // menuStrip // menuStrip.ImageScalingSize = new Size(24, 24); - menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem, отчетыToolStripMenuItem, startWorkToolStripMenuItem, mailToolStripMenuItem }); + menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem, отчетыToolStripMenuItem, startWorkToolStripMenuItem, mailToolStripMenuItem, createBackupToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; menuStrip.Size = new Size(1666, 33); @@ -140,6 +141,13 @@ startWorkToolStripMenuItem.Text = "Запуск работ"; startWorkToolStripMenuItem.Click += startWorkToolStripMenuItem_Click; // + // mailToolStripMenuItem + // + mailToolStripMenuItem.Name = "mailToolStripMenuItem"; + mailToolStripMenuItem.Size = new Size(90, 29); + mailToolStripMenuItem.Text = "Письма"; + mailToolStripMenuItem.Click += mailToolStripMenuItem_Click; + // // buttonCreateOrder // buttonCreateOrder.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -195,12 +203,12 @@ buttonRef.UseVisualStyleBackColor = true; buttonRef.Click += buttonRef_Click; // - // mailToolStripMenuItem + // createBackupToolStripMenuItem // - mailToolStripMenuItem.Name = "mailToolStripMenuItem"; - mailToolStripMenuItem.Size = new Size(90, 29); - mailToolStripMenuItem.Text = "Письма"; - mailToolStripMenuItem.Click += mailToolStripMenuItem_Click; + createBackupToolStripMenuItem.Name = "createBackupToolStripMenuItem"; + createBackupToolStripMenuItem.Size = new Size(145, 29); + createBackupToolStripMenuItem.Text = "Создать бекап"; + createBackupToolStripMenuItem.Click += createBackupToolStripMenuItem_Click; // // FormMain // @@ -245,5 +253,6 @@ private ToolStripMenuItem startWorkToolStripMenuItem; private ToolStripMenuItem implementersToolStripMenuItem; private ToolStripMenuItem mailToolStripMenuItem; + private ToolStripMenuItem createBackupToolStripMenuItem; } } \ No newline at end of file diff --git a/Confectionery/ConfectioneryView/FormMain.cs b/Confectionery/ConfectioneryView/FormMain.cs index 03aa49d..86ce360 100644 --- a/Confectionery/ConfectioneryView/FormMain.cs +++ b/Confectionery/ConfectioneryView/FormMain.cs @@ -1,6 +1,8 @@ -using ConfectioneryContracts.BindingModels; +using ConfectioneryBusinessLogic; +using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; using Microsoft.Extensions.Logging; +using ConfectioneryContracts.DI; using System; using System.Collections.Generic; using System.ComponentModel; @@ -19,14 +21,16 @@ namespace ConfectioneryView private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; private readonly IWorkProcess _workProcess; + private readonly IBackUpLogic _backUpLogic; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) + public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess, IBackUpLogic backUpLogic) { InitializeComponent(); _logger = logger; _orderLogic = orderLogic; _reportLogic = reportLogic; _workProcess = workProcess; + _backUpLogic = backUpLogic; } private void FormMain_Load(object sender, EventArgs e) { @@ -37,17 +41,7 @@ namespace ConfectioneryView _logger.LogInformation("Загрузка заказов"); try { - var list = _orderLogic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["PastryId"].Visible = false; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["ClientEmail"].Visible = false; - dataGridView.Columns["ImplementerId"].Visible = false; - dataGridView.Columns["PastryName"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_orderLogic.ReadList(null)); _logger.LogInformation("Загрузка заказов"); } catch (Exception ex) @@ -58,29 +52,20 @@ namespace ConfectioneryView } private void componentsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); - if (service is FormComponents form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void pastryToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormPastrys)); - if (service is FormPastrys 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 buttonTakeOrderInWork_Click(object sender, EventArgs e) @@ -168,21 +153,14 @@ namespace ConfectioneryView private void componentPastryToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportPastryComponents)); - if (service is FormReportPastryComponents form) - { - form.ShowDialog(); - } - + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void ordersListToolStripMenuItem_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 pastrysListToolStripMenuItem_Click(object sender, EventArgs e) @@ -201,34 +179,50 @@ namespace ConfectioneryView private void clientsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormClients)); - if (service is FormClients form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void 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 startWorkToolStripMenuItem_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(FormMail)); - if (service is FormMail 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/Confectionery/ConfectioneryView/FormPastry.cs b/Confectionery/ConfectioneryView/FormPastry.cs index ec9f503..f19d8ee 100644 --- a/Confectionery/ConfectioneryView/FormPastry.cs +++ b/Confectionery/ConfectioneryView/FormPastry.cs @@ -1,5 +1,6 @@ using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using ConfectioneryContracts.SearchModels; using ConfectioneryDataModels.Models; using Microsoft.Extensions.Logging; @@ -15,227 +16,217 @@ using System.Windows.Forms; namespace ConfectioneryView { - public partial class FormPastry : Form - { - private readonly ILogger _logger; - private readonly IPastryLogic _logic; - private int? _id; - private Dictionary _pastryComponents; - public int Id { set { _id = value; } } + public partial class FormPastry : Form + { + private readonly ILogger _logger; + private readonly IPastryLogic _logic; + private int? _id; + private Dictionary _pastryComponents; + public int Id { set { _id = value; } } - public FormPastry(ILogger logger, IPastryLogic logic) - { - InitializeComponent(); - _logger = logger; - _logic = logic; - _pastryComponents = new Dictionary(); - } + public FormPastry(ILogger logger, IPastryLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + _pastryComponents = new Dictionary(); + } - private void buttonSave_Click(object sender, EventArgs e) - { - if (string.IsNullOrEmpty(textBoxName.Text)) - { - MessageBox.Show("Заполните название", "Ошибка", - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - if (string.IsNullOrEmpty(textBoxPrice.Text)) - { - MessageBox.Show("Заполните цену", "Ошибка", MessageBoxButtons.OK, - MessageBoxIcon.Error); - return; - } - if (_pastryComponents == null || _pastryComponents.Count == 0) - { - MessageBox.Show("Заполните компоненты", "Ошибка", - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - _logger.LogInformation("Сохранение изделия"); - try - { - var model = new PastryBindingModel - { - Id = _id ?? 0, - PastryName = textBoxName.Text, - Price = Convert.ToDouble(textBoxPrice.Text), - PastryComponents = _pastryComponents - }; - var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model); - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); - DialogResult = DialogResult.OK; - Close(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка сохранения изделия"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } + private void buttonSave_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxName.Text)) + { + MessageBox.Show("Заполните название", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (string.IsNullOrEmpty(textBoxPrice.Text)) + { + MessageBox.Show("Заполните цену", "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); + return; + } + if (_pastryComponents == null || _pastryComponents.Count == 0) + { + MessageBox.Show("Заполните компоненты", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _logger.LogInformation("Сохранение изделия"); + try + { + var model = new PastryBindingModel + { + Id = _id ?? 0, + PastryName = textBoxName.Text, + Price = Convert.ToDouble(textBoxPrice.Text), + PastryComponents = _pastryComponents + }; + var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка сохранения изделия"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } - private void FormPastry_Load(object sender, EventArgs e) - { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.AllowUserToAddRows = false; - DataGridViewTextBoxColumn Id = new DataGridViewTextBoxColumn(); - DataGridViewTextBoxColumn Component = new DataGridViewTextBoxColumn(); - DataGridViewTextBoxColumn Number = new DataGridViewTextBoxColumn(); - Component.HeaderText = "Количество"; - Number.HeaderText = "Компонент"; - Number.Name = "Number"; - Id.Name = "Id"; - dataGridView.Columns.Add(Id); - dataGridView.Columns.Add(Number); - dataGridView.Columns.Add(Component); - dataGridView.Columns["Id"].Visible = false; + private void FormPastry_Load(object sender, EventArgs e) + { + var list = _logic.ReadList(null); + if (list != null) + { + dataGridView.AllowUserToAddRows = false; + DataGridViewTextBoxColumn Id = new DataGridViewTextBoxColumn(); + DataGridViewTextBoxColumn Component = new DataGridViewTextBoxColumn(); + DataGridViewTextBoxColumn Number = new DataGridViewTextBoxColumn(); + Component.HeaderText = "Количество"; + Number.HeaderText = "Компонент"; + Number.Name = "Number"; + Id.Name = "Id"; + dataGridView.Columns.Add(Id); + dataGridView.Columns.Add(Number); + dataGridView.Columns.Add(Component); + dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["Number"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } - if (_id.HasValue) - { - _logger.LogInformation("Загрузка суши"); - try - { - var view = _logic.ReadElement(new PastrySearchModel - { - Id = _id.Value - }); - if (view != null) - { - textBoxName.Text = view.PastryName; - textBoxPrice.Text = view.Price.ToString(); - _pastryComponents = view.PastryComponents ?? new - Dictionary(); - LoadData(); - } - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка загрузки суши"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, - MessageBoxIcon.Error); - } - } - } - private void LoadData() - { - _logger.LogInformation("Загрузка компонент изделия"); - try - { - if (_pastryComponents != null) - { - dataGridView.Rows.Clear(); - foreach (var pc in _pastryComponents) - { - dataGridView.Rows.Add(new object[] { pc.Key, pc.Value.Item1.ComponentName, pc.Value.Item2 }); - } - textBoxPrice.Text = CalcPrice().ToString(); - } - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка загрузки компонент изделия"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, - MessageBoxIcon.Error); - } - } + dataGridView.Columns["Number"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + } + if (_id.HasValue) + { + _logger.LogInformation("Загрузка суши"); + try + { + var view = _logic.ReadElement(new PastrySearchModel + { + Id = _id.Value + }); + if (view != null) + { + textBoxName.Text = view.PastryName; + textBoxPrice.Text = view.Price.ToString(); + _pastryComponents = view.PastryComponents ?? new + Dictionary(); + LoadData(); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки суши"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + } + private void LoadData() + { + _logger.LogInformation("Загрузка компонент изделия"); + try + { + if (_pastryComponents != null) + { + dataGridView.Rows.Clear(); + foreach (var pc in _pastryComponents) + { + dataGridView.Rows.Add(new object[] { pc.Key, pc.Value.Item1.ComponentName, pc.Value.Item2 }); + } + textBoxPrice.Text = CalcPrice().ToString(); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки компонент изделия"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } - private void buttonAdd_Click(object sender, EventArgs e) - { - var service = Program.ServiceProvider?.GetService(typeof(FormPastryComponent)); - if (service is FormPastryComponent form) - { - if (form.ShowDialog() == DialogResult.OK) - { - if (form.ComponentModel == null) - { - return; - } - _logger.LogInformation("Добавление нового компонента:{ComponentName} - {Count}", form.ComponentModel.ComponentName, form.Count); - if (_pastryComponents.ContainsKey(form.Id)) - { - _pastryComponents[form.Id] = (form.ComponentModel, - form.Count); - } - else - { - _pastryComponents.Add(form.Id, (form.ComponentModel, - form.Count)); - } - LoadData(); - } - } - } + private void buttonAdd_Click(object sender, EventArgs e) + { + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) + { + return; + } + _logger.LogInformation("Добавление нового ингридиента:{ ComponentName}-{ Count}", form.ComponentModel.ComponentName, form.Count); + if (_pastryComponents.ContainsKey(form.Id)) + { + _pastryComponents[form.Id] = (form.ComponentModel, + form.Count); + } + else + { + _pastryComponents.Add(form.Id, (form.ComponentModel, + form.Count)); + } + LoadData(); + } - private void buttonUpd_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - var service = - Program.ServiceProvider?.GetService(typeof(FormPastryComponent)); - if (service is FormPastryComponent form) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); - form.Id = id; - form.Count = _pastryComponents[id].Item2; - if (form.ShowDialog() == DialogResult.OK) - { - if (form.ComponentModel == null) - { - return; - } - _logger.LogInformation("Изменение компонента: {ComponentName} - {Count}", form.ComponentModel.ComponentName, form.Count); - _pastryComponents[form.Id] = (form.ComponentModel, form.Count); - LoadData(); - } - } - } - } + private void buttonUpd_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + var form = DependencyManager.Instance.Resolve(); + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); + form.Id = id; + form.Count = _pastryComponents[id].Item2; + if (form.ShowDialog() == DialogResult.OK) + { + if (form.ComponentModel == null) + { + return; + } + _logger.LogInformation("Изменение ингридиента:{ ComponentName}-{ Count}", form.ComponentModel.ComponentName, form.Count); + _pastryComponents[form.Id] = (form.ComponentModel, form.Count); + LoadData(); + } + } + } - private void buttonDel_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - if (MessageBox.Show("Удалить запись?", "Вопрос", - MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) - { - try - { - _logger.LogInformation("Удаление компонента: {ComponentName} - { Count}", dataGridView.SelectedRows[0].Cells[1].Value); _pastryComponents?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value)); - } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - LoadData(); - } - } - } + private void buttonDel_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + if (MessageBox.Show("Удалить запись?", "Вопрос", + MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + try + { + _logger.LogInformation("Удаление компонента: {ComponentName} - { Count}", dataGridView.SelectedRows[0].Cells[1].Value); _pastryComponents?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value)); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + LoadData(); + } + } + } - private void buttonRef_Click(object sender, EventArgs e) - { - LoadData(); - } + private void buttonRef_Click(object sender, EventArgs e) + { + LoadData(); + } - private void buttonCancel_Click(object sender, EventArgs e) - { - DialogResult = DialogResult.Cancel; - Close(); - } - private double CalcPrice() - { - double price = 0; - foreach (var elem in _pastryComponents) - { - price += ((elem.Value.Item1?.Cost ?? 0) * elem.Value.Item2); - } - return Math.Round(price * 1.1, 2); - } - } + private void buttonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + private double CalcPrice() + { + double price = 0; + foreach (var elem in _pastryComponents) + { + price += ((elem.Value.Item1?.Cost ?? 0) * elem.Value.Item2); + } + return Math.Round(price * 1.1, 2); + } + } } diff --git a/Confectionery/ConfectioneryView/FormPastrys.cs b/Confectionery/ConfectioneryView/FormPastrys.cs index c416875..1a5cbf9 100644 --- a/Confectionery/ConfectioneryView/FormPastrys.cs +++ b/Confectionery/ConfectioneryView/FormPastrys.cs @@ -10,105 +10,92 @@ using System.Windows.Forms; using Microsoft.Extensions.Logging; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; namespace ConfectioneryView { - public partial class FormPastrys : Form - { - private readonly ILogger _logger; - private readonly IPastryLogic _logic; - public FormPastrys(ILogger logger, IPastryLogic logic) - { - InitializeComponent(); - _logger = logger; - _logic = logic; - } - private void FormPastrys_Load(object sender, EventArgs e) - { - LoadData(); - } + public partial class FormPastrys : Form + { + private readonly ILogger _logger; + private readonly IPastryLogic _logic; + public FormPastrys(ILogger logger, IPastryLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + } + private void FormPastrys_Load(object sender, EventArgs e) + { + LoadData(); + } - private void LoadData() - { - try - { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["PastryComponents"].Visible = false; - dataGridView.Columns["PastryName"].AutoSizeMode = - DataGridViewAutoSizeColumnMode.Fill; - } - _logger.LogInformation("Загрузка кондитерского изделия"); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка загрузки кондитерского изделия"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } + private void LoadData() + { + try + { + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка кондитерского изделия"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки кондитерского изделия"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } - private void buttonAdd_Click(object sender, EventArgs e) - { - var service = Program.ServiceProvider?.GetService(typeof(FormPastry)); - if (service is FormPastry form) - { - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } - } - } + private void buttonAdd_Click(object sender, EventArgs e) + { + 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(FormPastry)); - if (service is FormPastry form) - { - form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - if (form.ShowDialog() == DialogResult.OK) - { - LoadData(); - } - } - } - } + private void buttonUpd_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { + LoadData(); + } + } + } - private void buttonDel_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Удаление кондитерского изделия"); - try - { - if (!_logic.Delete(new PastryBindingModel - { - Id = id - })) - { - throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); - } - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка удаления кондитерского изделия"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - } + private void buttonDel_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Удаление кондитерского изделия"); + try + { + if (!_logic.Delete(new PastryBindingModel + { + Id = id + })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления кондитерского изделия"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } - private void buttonRef_Click(object sender, EventArgs e) - { - LoadData(); - } - } + private void buttonRef_Click(object sender, EventArgs e) + { + LoadData(); + } + } } diff --git a/Confectionery/ConfectioneryView/Program.cs b/Confectionery/ConfectioneryView/Program.cs index 0ce7e90..627269f 100644 --- a/Confectionery/ConfectioneryView/Program.cs +++ b/Confectionery/ConfectioneryView/Program.cs @@ -10,6 +10,7 @@ using NLog.Extensions.Logging; using ConfectioneryBusinessLogic.BusinessLogics; using Microsoft.EntityFrameworkCore.Design; using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.DI; namespace ConfectioneryView { @@ -25,12 +26,10 @@ namespace ConfectioneryView static void Main() { ApplicationConfiguration.Initialize(); - var services = new ServiceCollection(); - ConfigureServices(services); - _serviceProvider = services.BuildServiceProvider(); + InitDependency(); try { - var mailSender = _serviceProvider.GetService(); + var mailSender = DependencyManager.Instance.Resolve(); mailSender?.MailConfig(new MailConfigBindingModel { MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty, @@ -45,55 +44,59 @@ namespace ConfectioneryView } catch (Exception ex) { - var logger = _serviceProvider.GetService(); + var logger = DependencyManager.Instance.Resolve(); logger?.LogError(ex, "Mails Problem"); } - Application.Run(_serviceProvider.GetRequiredService()); + Application.Run(DependencyManager.Instance.Resolve()); } - private static void ConfigureServices(ServiceCollection services) + private static void InitDependency() { - services.AddLogging(option => + DependencyManager.InitDependency(); + + DependencyManager.Instance.AddLogging(option => { option.SetMinimumLevel(LogLevel.Information); option.AddNLog("nlog.config"); }); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - 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(true); - services.AddTransient(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + + 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 -- 2.25.1 From 60260c29e1e81acd96cd208041271db681cf63f1 Mon Sep 17 00:00:00 2001 From: malimova Date: Tue, 4 Jun 2024 08:52:40 +0400 Subject: [PATCH 2/2] +dll, finish --- .../ConfectioneryContracts.csproj | 2 ++ .../ConfectioneryContracts.dll | Bin 0 -> 31744 bytes .../ConfectioneryDataModels.dll | Bin 0 -> 6144 bytes .../ConfectioneryDatabaseImplement.dll | Bin 0 -> 81920 bytes .../ConfectioneryFileImplement.dll | Bin 0 -> 40960 bytes .../ConfectioneryListImplement.dll | Bin 0 -> 26624 bytes 6 files changed, 2 insertions(+) create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryContracts.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryDataModels.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryDatabaseImplement.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryFileImplement.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryListImplement.dll diff --git a/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj b/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj index 75c03cc..76424bf 100644 --- a/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj +++ b/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj @@ -9,6 +9,8 @@ + + diff --git a/Confectionery/ImplementationExtensions/ConfectioneryContracts.dll b/Confectionery/ImplementationExtensions/ConfectioneryContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..ddbae4ac2776b695a6de5b8313c25ab77258f337 GIT binary patch literal 31744 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 literal 0 HcmV?d00001 diff --git a/Confectionery/ImplementationExtensions/ConfectioneryDataModels.dll b/Confectionery/ImplementationExtensions/ConfectioneryDataModels.dll new file mode 100644 index 0000000000000000000000000000000000000000..42e7ceb743540fa7d6470e8e57e7d55d9ab5fd8a GIT binary patch literal 6144 zcmeHLYm6IL6+UCn?mGKQoOhapIBY^UP2%omU)i>4_hBb>$v(2)JZM+!j_tdfNyZ*` zX1vKF5tg7LXhA8Bgw!7mX{$&T1QC@4BGLq;(jY(;UJyT!q6!fS2?+@*0RjYs@7x*N zwa_3Kp!T7%BmxY$elvspmt`IZJ{MShMjBx|Y)n4O4`xyg z?2d4wkLVwqh`Y-aQ6qTjPNMOt&L?Dh@ zwv`4Yed|Mm16_{lD}C@jY6-)HBKt~HsBCLBs;~4B4fsge?B%?oux|mXq0tD@Wf)PI z`2os6@`(Y(>&?E*c1GKx9c>-$y=<(84B%@uL@lR?R$^{%A)c0`W9hjWn>GGe?}pfN zFiC$xo2RU0-@!x-Pql&Q5*%w8Fw7JyqaaM>@TT+15+?qxba2e<`wCR%@$y-Z$~@e&SJelDg61C;bpwLw31wMzDG6?IfS?CbYnm8`no&#K1j3;IVt zRn_ktJ>|3cn=09-)U;35r~3VTx{CTn)p+Nss4rEG@JZG0OGnTj(Khv{Z@dQ-|LFVG ztWOqH{Jy+Jek&{0*|MgJGo=Q#7PStQe@kS|VAX~xgH^Q-SWnx4%cxyquf%?d35f?J zenO%KROo5oDw-?febV+eU?W9=%cujml6C{v(jMA^wfUm5m5x(_?ng#0C{b#lYtUUm zKLoC)+rSq3J#afc0BHy913pY+z(JY>eq8dCz__#{Bz}(4bXIvrwqKR)HzmF$Ik#oI z1-U${=t1@&fb6L9?5aUt>hNoTk749x9hU1A!YhFG(iegCLB=;^`_B>$^~>ON$hOP> zh18D)xz}mQe}%q+_HSkTl=>ptF_rBUBz{ZkzasH@shLu_Z%>dd_p0ZBQH6Vrs;>g; z6z=l=HaE=8qL+gM| z$a#R8X(MncZ2~T%&A>2bA%IuLR^STERRFWN4Y&&P62Nh}6S#&R1g^z;3BXnd@ILAS zuBRSS=iSp24ts^qB>%fDLhI#WP|Z`yuVfl77>1TI#8f*S(u{%_FXTb&qL`j`bTg+} zb08iWGBX83JW4adnM`D%krg>dSbGyAk~L`PpqZLw8?R6(eI}I;l+yXKoA=YFGH26Wx%?W5Uo*%9c-Fie%KnQb;?Mj-{Y69)CAg z1f?EqS$JO|*O2MU^@PwQ!!vhuPK z)85LbXxcHY5_zLaV|ZKXZ4yQ6I| z(7dvI0L64WZ)kIT{)MP*!0TF}8hHZZR)gW%ago3euWN;(lGrZV+Pb=T zwRMYhrY9phx>N1xbWg9A?$orluJ$g`o@wjpNu|5+$I=kKn#{WNBH zd?rQ7$NP76b(80a^MvOJf_>z#lNY`n&aSz5AbxA(PVW-Pp6}y!gj@HP(q++=Ok&Ps zhB2h+Im+5;EC3;oFt6X8tuS+UTJE*^A?JT61B#rmwM6sPPRZRv*n9WzS&#oaIMPRS zo;R0Q&IdcuI)wYzBrr~6XeDru8U~#J?nRr+b@dPba=$NmcW`l^kGTZCh26h0JW@Vl zKm}GcvS3HYe+mLNb2Lq+ly8x}#v#?fwISEYfu0G3Ij%#nYr%3Q5AC>{wUsOTu>ty=Nk{7D;H}|{?EQ@& zMT7=^M6I|(MX;+Q*!(fkI%EhW4dTqp;7} zFUZ;XZ|3bZZcPeSgWulWS+3-GJL2b+)J5I23(s!QY5372S3(Eq6z*SX{CcPtv8JgL zsL3Af=q30z52^>h6r^~oq40fNp?=J(4UH@$1~MDL?x>#aiXS}Zz7lc&Gn{zT$NRAP If0KcK1K6DVssI20 literal 0 HcmV?d00001 diff --git a/Confectionery/ImplementationExtensions/ConfectioneryDatabaseImplement.dll b/Confectionery/ImplementationExtensions/ConfectioneryDatabaseImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..9aa1d19de8056eb8ff3864ce4cf52fd40f5c25aa GIT binary patch literal 81920 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 C{~H1T literal 0 HcmV?d00001 diff --git a/Confectionery/ImplementationExtensions/ConfectioneryFileImplement.dll b/Confectionery/ImplementationExtensions/ConfectioneryFileImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..ad32f90ddcd88a3819d0420c57a2c09cb9797388 GIT binary patch literal 40960 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 literal 0 HcmV?d00001 -- 2.25.1