From 3d35c44a4c60d770e9fd3a27210b5ecafc5a52d6 Mon Sep 17 00:00:00 2001 From: Marselchi Date: Mon, 20 May 2024 11:21:09 +0400 Subject: [PATCH] =?UTF-8?q?8-=D0=B0=D1=8F=20=D1=81=D0=B4=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ShipyardContracts.dll | Bin 0 -> 31744 bytes .../ShipyardDataBaseImplement.dll | Bin 0 -> 79872 bytes .../ShipyardDataModels.dll | Bin 0 -> 6144 bytes .../ShipyardFileImplement.dll | Bin 0 -> 40448 bytes .../ShipyardListImplement.dll | Bin 0 -> 25600 bytes .../BusinessLogics/BackUpLogic.cs | 99 +++++++++++++ .../Attributes/ColumnAttribute.cs | 25 ++++ .../Attributes/GridViewAutoSize.cs | 21 +++ .../BindingModels/BackUpSaveBindingModel.cs | 7 + .../BindingModels/MessageInfoBindingModel.cs | 1 + .../BusinessLogicsContracts/IBackUpLogic.cs | 8 ++ .../ShipyardContracts/DI/DependencyManager.cs | 61 ++++++++ .../DI/IDependencyContainer.cs | 35 +++++ .../DI/IImplementationExtension.cs | 11 ++ .../DI/ServiceDependencyContainer.cs | 62 ++++++++ .../DI/ServiceProviderLoader.cs | 50 +++++++ .../DI/UnityDependencyContainer.cs | 38 +++++ .../ShipyardContracts.csproj | 9 +- .../StoragesContracts/IBackUpInfo.cs | 9 ++ .../ViewModels/ClientViewModel.cs | 8 +- .../ViewModels/DetailViewModel.cs | 6 +- .../ViewModels/ImplementerViewModel.cs | 20 +-- .../ViewModels/MessageInfoViewModel.cs | 14 +- .../ViewModels/OrderViewModel.cs | 24 ++-- .../ViewModels/ShipViewModel.cs | 7 +- .../DataBaseImplementationExtension.cs | 22 +++ .../Implements/BackUpInfo.cs | 27 ++++ .../Models/Client.cs | 6 + .../Models/Detail.cs | 5 + .../Models/Implementer.cs | 19 ++- .../Models/Message.cs | 5 + .../ShipyardDataBaseImplement/Models/Order.cs | 13 +- .../ShipyardDataBaseImplement/Models/Ship.cs | 6 + .../ShipyardDataBaseImplement.csproj | 4 + .../Models/IMessageInfoModel.cs | 2 +- .../FileImplementationExtension.cs | 22 +++ .../Implements/BackUpInfo.cs | 29 ++++ .../ShipyardFileImplement/Models/Client.cs | 6 + .../ShipyardFileImplement/Models/Detail.cs | 5 + .../Models/Implementer.cs | 23 +-- .../ShipyardFileImplement/Models/Message.cs | 14 +- .../ShipyardFileImplement/Models/Order.cs | 11 ++ Shipyard/ShipyardFileImplement/Models/Ship.cs | 6 + .../ShipyardFileImplement.csproj | 5 +- .../Implements/BackUpInfo.cs | 17 +++ .../ListImplementationExtension.cs | 22 +++ .../ShipyardListImplement/Models/Message.cs | 2 +- .../ShipyardListImplement.csproj | 4 + .../ShipyardView/DataGridViewExtension.cs | 45 ++++++ Shipyard/ShipyardView/FormClients.cs | 8 +- Shipyard/ShipyardView/FormDetails.Designer.cs | 1 + Shipyard/ShipyardView/FormDetails.cs | 25 +--- Shipyard/ShipyardView/FormImplementers.cs | 34 ++--- Shipyard/ShipyardView/FormMails.cs | 9 +- Shipyard/ShipyardView/FormMain.Designer.cs | 14 +- Shipyard/ShipyardView/FormMain.cs | 134 +++++++++--------- Shipyard/ShipyardView/FormMain.resx | 11 ++ Shipyard/ShipyardView/FormShip.cs | 55 ++++--- Shipyard/ShipyardView/FormShips.cs | 26 +--- Shipyard/ShipyardView/Program.cs | 80 +++++------ Shipyard/ShipyardView/ShipyardView.csproj | 2 +- 61 files changed, 958 insertions(+), 276 deletions(-) create mode 100644 Shipyard/ImplementationExtensions/ShipyardContracts.dll create mode 100644 Shipyard/ImplementationExtensions/ShipyardDataBaseImplement.dll create mode 100644 Shipyard/ImplementationExtensions/ShipyardDataModels.dll create mode 100644 Shipyard/ImplementationExtensions/ShipyardFileImplement.dll create mode 100644 Shipyard/ImplementationExtensions/ShipyardListImplement.dll create mode 100644 Shipyard/ShipyardBusinessLogic/BusinessLogics/BackUpLogic.cs create mode 100644 Shipyard/ShipyardContracts/Attributes/ColumnAttribute.cs create mode 100644 Shipyard/ShipyardContracts/Attributes/GridViewAutoSize.cs create mode 100644 Shipyard/ShipyardContracts/BindingModels/BackUpSaveBindingModel.cs create mode 100644 Shipyard/ShipyardContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 Shipyard/ShipyardContracts/DI/DependencyManager.cs create mode 100644 Shipyard/ShipyardContracts/DI/IDependencyContainer.cs create mode 100644 Shipyard/ShipyardContracts/DI/IImplementationExtension.cs create mode 100644 Shipyard/ShipyardContracts/DI/ServiceDependencyContainer.cs create mode 100644 Shipyard/ShipyardContracts/DI/ServiceProviderLoader.cs create mode 100644 Shipyard/ShipyardContracts/DI/UnityDependencyContainer.cs create mode 100644 Shipyard/ShipyardContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 Shipyard/ShipyardDataBaseImplement/DataBaseImplementationExtension.cs create mode 100644 Shipyard/ShipyardDataBaseImplement/Implements/BackUpInfo.cs create mode 100644 Shipyard/ShipyardFileImplement/FileImplementationExtension.cs create mode 100644 Shipyard/ShipyardFileImplement/Implements/BackUpInfo.cs create mode 100644 Shipyard/ShipyardListImplement/Implements/BackUpInfo.cs create mode 100644 Shipyard/ShipyardListImplement/ListImplementationExtension.cs create mode 100644 Shipyard/ShipyardView/DataGridViewExtension.cs diff --git a/Shipyard/ImplementationExtensions/ShipyardContracts.dll b/Shipyard/ImplementationExtensions/ShipyardContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..f17efa8a6af019bb6bb39246e217d0ced64e5b5b GIT binary patch literal 31744 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 literal 0 HcmV?d00001 diff --git a/Shipyard/ImplementationExtensions/ShipyardDataBaseImplement.dll b/Shipyard/ImplementationExtensions/ShipyardDataBaseImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..293c34309c91e776f3334b16a2f783f6ba3ae9fa GIT binary patch literal 79872 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 Ohkm`({*AWU0{;hHu8bA{ literal 0 HcmV?d00001 diff --git a/Shipyard/ImplementationExtensions/ShipyardDataModels.dll b/Shipyard/ImplementationExtensions/ShipyardDataModels.dll new file mode 100644 index 0000000000000000000000000000000000000000..adb9530136d8ba403268857412a8e9d17ff118b2 GIT binary patch literal 6144 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 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/Shipyard/ShipyardContracts/Attributes/ColumnAttribute.cs b/Shipyard/ShipyardContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..54ddec8 --- /dev/null +++ b/Shipyard/ShipyardContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,25 @@ +namespace ShipyardContracts.Attributes +{ + [AttributeUsage(AttributeTargets.Property)] + public class ColumnAttribute : Attribute + { + 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; } + + 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; + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/Attributes/GridViewAutoSize.cs b/Shipyard/ShipyardContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..2357359 --- /dev/null +++ b/Shipyard/ShipyardContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,21 @@ +namespace ShipyardContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + + None = 1, + + ColumnHeader = 2, + + AllCellsExceptHeader = 4, + + AllCells = 6, + + DisplayedCellsExceptHeader = 8, + + DisplayedCells = 10, + + Fill = 16 + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/BindingModels/BackUpSaveBindingModel.cs b/Shipyard/ShipyardContracts/BindingModels/BackUpSaveBindingModel.cs new file mode 100644 index 0000000..aceed9e --- /dev/null +++ b/Shipyard/ShipyardContracts/BindingModels/BackUpSaveBindingModel.cs @@ -0,0 +1,7 @@ +namespace ShipyardContracts.BindingModels +{ + public class BackUpSaveBinidngModel + { + public string FolderName { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/BindingModels/MessageInfoBindingModel.cs b/Shipyard/ShipyardContracts/BindingModels/MessageInfoBindingModel.cs index 8d96e70..93f4748 100644 --- a/Shipyard/ShipyardContracts/BindingModels/MessageInfoBindingModel.cs +++ b/Shipyard/ShipyardContracts/BindingModels/MessageInfoBindingModel.cs @@ -15,5 +15,6 @@ namespace ShipyardContracts.BindingModels public string Body { get; set; } = string.Empty; public DateTime DateDelivery { get; set; } + public int Id => throw new NotImplementedException(); } } \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/BusinessLogicsContracts/IBackUpLogic.cs b/Shipyard/ShipyardContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..87759df --- /dev/null +++ b/Shipyard/ShipyardContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,8 @@ +using ShipyardContracts.BindingModels; +namespace ShipyardContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBinidngModel model); + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/DI/DependencyManager.cs b/Shipyard/ShipyardContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..7d65641 --- /dev/null +++ b/Shipyard/ShipyardContracts/DI/DependencyManager.cs @@ -0,0 +1,61 @@ +using Microsoft.Extensions.Logging; + +namespace ShipyardContracts.DI +{ + public class DependencyManager + { + private readonly IDependencyContainer _dependencyManager; + + private static DependencyManager? _manager; + + private static readonly object _locjObject = new(); + + private DependencyManager() + { + _dependencyManager = new UnityDependencyContainer(); + } + + public static DependencyManager Instance { get { if (_manager == null) { lock (_locjObject) { _manager = new DependencyManager(); } } return _manager; } } + + /// + /// Иницализация библиотек, в которых идут установки зависомстей + /// + public static void InitDependency() + { + var ext = ServiceProviderLoader.GetImplementationExtensions(); + if (ext == null) + { + throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям"); + } + // регистрируем зависимости + ext.RegisterServices(); + } + + /// + /// Регистрация логгера + /// + /// + public void AddLogging(Action configure) => _dependencyManager.AddLogging(configure); + + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where U : class, T where T : class => _dependencyManager.RegisterType(isSingle); + + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where T : class => _dependencyManager.RegisterType(isSingle); + + /// + /// Получение класса со всеми зависмостями + /// + /// + /// + public T Resolve() => _dependencyManager.Resolve(); + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/DI/IDependencyContainer.cs b/Shipyard/ShipyardContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..715365f --- /dev/null +++ b/Shipyard/ShipyardContracts/DI/IDependencyContainer.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Logging; + +namespace ShipyardContracts.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(); + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/DI/IImplementationExtension.cs b/Shipyard/ShipyardContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..55f0214 --- /dev/null +++ b/Shipyard/ShipyardContracts/DI/IImplementationExtension.cs @@ -0,0 +1,11 @@ +namespace ShipyardContracts.DI +{ + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/DI/ServiceDependencyContainer.cs b/Shipyard/ShipyardContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..5018223 --- /dev/null +++ b/Shipyard/ShipyardContracts/DI/ServiceDependencyContainer.cs @@ -0,0 +1,62 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ShipyardContracts.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()!; + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/DI/ServiceProviderLoader.cs b/Shipyard/ShipyardContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..a7cbd1f --- /dev/null +++ b/Shipyard/ShipyardContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,50 @@ +using System.Reflection; + +namespace ShipyardContracts.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"; + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/DI/UnityDependencyContainer.cs b/Shipyard/ShipyardContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..ebb2fc7 --- /dev/null +++ b/Shipyard/ShipyardContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Logging; +using Unity.Microsoft.Logging; +using Unity; + +namespace ShipyardContracts.DI +{ + public class UnityDependencyContainer : IDependencyContainer + { + private readonly IUnityContainer _container; + + public UnityDependencyContainer() + { + _container = new UnityContainer(); + } + + public void AddLogging(Action configure) + { + var factory = LoggerFactory.Create(configure); + _container.AddExtension(new LoggingExtension(factory)); + } + + public void RegisterType(bool isSingle) where T : class + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + + } + + public T Resolve() + { + return _container.Resolve(); + } + + void IDependencyContainer.RegisterType(bool isSingle) + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/ShipyardContracts.csproj b/Shipyard/ShipyardContracts/ShipyardContracts.csproj index b446267..9c7532e 100644 --- a/Shipyard/ShipyardContracts/ShipyardContracts.csproj +++ b/Shipyard/ShipyardContracts/ShipyardContracts.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,6 +6,13 @@ enable + + + + + + + diff --git a/Shipyard/ShipyardContracts/StoragesContracts/IBackUpInfo.cs b/Shipyard/ShipyardContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..990bfdf --- /dev/null +++ b/Shipyard/ShipyardContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,9 @@ +namespace ShipyardContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/ViewModels/ClientViewModel.cs b/Shipyard/ShipyardContracts/ViewModels/ClientViewModel.cs index bf50722..4e13937 100644 --- a/Shipyard/ShipyardContracts/ViewModels/ClientViewModel.cs +++ b/Shipyard/ShipyardContracts/ViewModels/ClientViewModel.cs @@ -1,19 +1,21 @@ using ShipyardDataModels.Models; using System.ComponentModel; +using ShipyardContracts.Attributes; namespace ShipyardContracts.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; } } \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/ViewModels/DetailViewModel.cs b/Shipyard/ShipyardContracts/ViewModels/DetailViewModel.cs index 321c7b4..bb55edf 100644 --- a/Shipyard/ShipyardContracts/ViewModels/DetailViewModel.cs +++ b/Shipyard/ShipyardContracts/ViewModels/DetailViewModel.cs @@ -1,14 +1,16 @@ using ShipyardDataModels.Models; using System.ComponentModel; +using ShipyardContracts.Attributes; namespace ShipyardContracts.ViewModels { public class DetailViewModel : IDetailModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Название детали")] + [Column(title: "Название детали", width: 150)] public string DetailName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column(title: "Цена", width: 150)] public double Cost { get; set; } } diff --git a/Shipyard/ShipyardContracts/ViewModels/ImplementerViewModel.cs b/Shipyard/ShipyardContracts/ViewModels/ImplementerViewModel.cs index b13aa0c..7d6627e 100644 --- a/Shipyard/ShipyardContracts/ViewModels/ImplementerViewModel.cs +++ b/Shipyard/ShipyardContracts/ViewModels/ImplementerViewModel.cs @@ -1,22 +1,24 @@ using ShipyardDataModels.Models; using System.ComponentModel; +using ShipyardContracts.Attributes; namespace ShipyardContracts.ViewModels { public class ImplementerViewModel : IImplementerModel { - public int Id { get; set; } + [Column(visible: false)] + public int Id { get; set; } - [DisplayName("ФИО исполнителя")] - public string ImplementerFIO { get; set; } = string.Empty; + [Column(title: "ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Пароль")] - public string Password { get; set; } = string.Empty; + [Column(title: "Пароль", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string Password { get; set; } = string.Empty; - [DisplayName("Стаж работы")] - public int WorkExperience { get; set; } + [Column(title: "Стаж работы", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public int WorkExperience { get; set; } - [DisplayName("Квалификация")] - public int Qualification { get; set; } + [Column(title: "Квалификация", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public int Qualification { get; set; } } } \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/ViewModels/MessageInfoViewModel.cs b/Shipyard/ShipyardContracts/ViewModels/MessageInfoViewModel.cs index 03bfc46..a54e2e9 100644 --- a/Shipyard/ShipyardContracts/ViewModels/MessageInfoViewModel.cs +++ b/Shipyard/ShipyardContracts/ViewModels/MessageInfoViewModel.cs @@ -1,24 +1,28 @@ using ShipyardDataModels.Models; using System.ComponentModel; +using ShipyardContracts.Attributes; namespace ShipyardContracts.ViewModels { public class MessageInfoViewModel : IMessageInfoModel { + [Column(visible: false)] public string MessageId { get; set; } = string.Empty; - + [Column(visible: false)] public int? ClientId { get; set; } - [DisplayName("Отправитель")] + [Column(title: "Отправитель", width: 150)] public string SenderName { get; set; } = string.Empty; - [DisplayName("Дата письма")] + [Column(title: "Дата письма", width: 150)] public DateTime DateDelivery { get; set; } - [DisplayName("Заголовок")] + [Column(title: "Заголовок", width: 150)] public string Subject { get; set; } = string.Empty; - [DisplayName("Текст")] + [Column(title: "Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string Body { get; set; } = string.Empty; + [Column(visible: false)] + public int Id => throw new NotImplementedException(); } } \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/ViewModels/OrderViewModel.cs b/Shipyard/ShipyardContracts/ViewModels/OrderViewModel.cs index 5fd28c3..19471c8 100644 --- a/Shipyard/ShipyardContracts/ViewModels/OrderViewModel.cs +++ b/Shipyard/ShipyardContracts/ViewModels/OrderViewModel.cs @@ -1,31 +1,35 @@ using ShipyardDataModels.Enums; using ShipyardDataModels.Models; using System.ComponentModel; +using ShipyardContracts.Attributes; namespace ShipyardContracts.ViewModels { public class OrderViewModel : IOrderModel { - [DisplayName("Номер")] + [Column(title: "Номер", width: 150)] public int Id { get; set; } + [Column(visible: false)] public int ShipId { get; set; } - [DisplayName("Название")] + [Column(title: "Название", width: 150)] public string ShipName { get; set; } = string.Empty; + [Column(visible: false)] public int ClientId { get; set; } - [DisplayName("Клиент")] + [Column(title: "Клиент", width: 150)] public string ClientFIO { get; set; } = string.Empty; - public int? ImplementerId { get; set; } - [DisplayName("Исполнитель")] + [Column(visible: false)] + public int? ImplementerId { get; set; } + [Column(title: "Исполнитель", width: 150)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Количество")] + [Column(title: "Количество", width: 150)] public int Count { get; set; } - [DisplayName("Сумма")] + [Column(title: "Сумма", width: 150)] public double Sum { get; set; } - [DisplayName("Статус")] + [Column(title: "Статус", width: 150)] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; - [DisplayName("Дата создания")] + [Column(title: "Дата создания", width: 150)] public DateTime DateCreate { get; set; } = DateTime.Now; - [DisplayName("Дата выполнения")] + [Column(title: "Дата выполнения", width: 150)] public DateTime? DateImplement { get; set; } } } \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/ViewModels/ShipViewModel.cs b/Shipyard/ShipyardContracts/ViewModels/ShipViewModel.cs index 72b4429..829b964 100644 --- a/Shipyard/ShipyardContracts/ViewModels/ShipViewModel.cs +++ b/Shipyard/ShipyardContracts/ViewModels/ShipViewModel.cs @@ -1,15 +1,18 @@ using ShipyardDataModels.Models; using System.ComponentModel; +using ShipyardContracts.Attributes; namespace ShipyardContracts.ViewModels { public class ShipViewModel : IShipModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Название корабля")] + [Column(title: "Название корабля", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ShipName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column(title: "Цена", width: 150)] public double Price { get; set; } + [Column(visible: false)] public Dictionary ShipDetails { get; set; } = new(); } } \ No newline at end of file diff --git a/Shipyard/ShipyardDataBaseImplement/DataBaseImplementationExtension.cs b/Shipyard/ShipyardDataBaseImplement/DataBaseImplementationExtension.cs new file mode 100644 index 0000000..ce37fd8 --- /dev/null +++ b/Shipyard/ShipyardDataBaseImplement/DataBaseImplementationExtension.cs @@ -0,0 +1,22 @@ +using ShipyardContracts.DI; +using ShipyardContracts.StoragesContracts; +using ShipyardDataBaseImplement.Implements; + +namespace ShipyardDataBaseImplement +{ + 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(); + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardDataBaseImplement/Implements/BackUpInfo.cs b/Shipyard/ShipyardDataBaseImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..effcf31 --- /dev/null +++ b/Shipyard/ShipyardDataBaseImplement/Implements/BackUpInfo.cs @@ -0,0 +1,27 @@ +using ShipyardContracts.StoragesContracts; + +namespace ShipyardDataBaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new ShipyardDataBase(); + 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; + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardDataBaseImplement/Models/Client.cs b/Shipyard/ShipyardDataBaseImplement/Models/Client.cs index 20a3794..a16099e 100644 --- a/Shipyard/ShipyardDataBaseImplement/Models/Client.cs +++ b/Shipyard/ShipyardDataBaseImplement/Models/Client.cs @@ -3,17 +3,23 @@ using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace ShipyardDataBaseImplement.Models { + [DataContract] public class Client : IClientModel { + [DataMember] public int Id { get; set; } [Required] + [DataMember] public string ClientFIO { get; set; } = string.Empty; [Required] + [DataMember] public string Email { get; set; } = string.Empty; [Required] + [DataMember] public string Password { get; set; } = string.Empty; [ForeignKey("ClientId")] public virtual List Orders { get; set; } = new(); diff --git a/Shipyard/ShipyardDataBaseImplement/Models/Detail.cs b/Shipyard/ShipyardDataBaseImplement/Models/Detail.cs index e7e05a3..bbb3419 100644 --- a/Shipyard/ShipyardDataBaseImplement/Models/Detail.cs +++ b/Shipyard/ShipyardDataBaseImplement/Models/Detail.cs @@ -3,15 +3,20 @@ using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace ShipyardDataBaseImplement.Models { + [DataContract] public class Detail : IDetailModel { + [DataMember] public int Id { get; private set; } [Required] + [DataMember] public string DetailName { get; private set; } = string.Empty; [Required] + [DataMember] public double Cost { get; set; } [ForeignKey("DetailId")] public virtual List ShipDetails { get; set; } = new(); diff --git a/Shipyard/ShipyardDataBaseImplement/Models/Implementer.cs b/Shipyard/ShipyardDataBaseImplement/Models/Implementer.cs index 8641d50..58e0bef 100644 --- a/Shipyard/ShipyardDataBaseImplement/Models/Implementer.cs +++ b/Shipyard/ShipyardDataBaseImplement/Models/Implementer.cs @@ -3,24 +3,31 @@ using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace ShipyardDataBaseImplement.Models { - public class Implementer : IImplementerModel + [DataContract] + public class Implementer : IImplementerModel { - public int Id { get; set; } + [DataMember] + public int Id { get; set; } [Required] - public string ImplementerFIO { get; set; } = String.Empty; + [DataMember] + public string ImplementerFIO { get; set; } = String.Empty; [Required] - public string Password { get; set; } = String.Empty; + [DataMember] + public string Password { get; set; } = String.Empty; [Required] - public int WorkExperience { get; set; } + [DataMember] + public int WorkExperience { get; set; } [Required] - public int Qualification { get; set; } + [DataMember] + public int Qualification { get; set; } [ForeignKey("ImplementerId")] public virtual List Orders { get; set; } = new(); diff --git a/Shipyard/ShipyardDataBaseImplement/Models/Message.cs b/Shipyard/ShipyardDataBaseImplement/Models/Message.cs index faba572..a406a7c 100644 --- a/Shipyard/ShipyardDataBaseImplement/Models/Message.cs +++ b/Shipyard/ShipyardDataBaseImplement/Models/Message.cs @@ -2,12 +2,15 @@ using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace ShipyardDataBaseImplement.Models { + [DataContract] public class Message : IMessageInfoModel { [Key] + [DataMember] public string MessageId { get; private set; } = string.Empty; public int? ClientId { get; private set; } @@ -20,6 +23,8 @@ namespace ShipyardDataBaseImplement.Models public string Body { get; private set; } = string.Empty; + public int Id => throw new NotImplementedException(); + public Client? Client { get; private set; } public static Message? Create(MessageInfoBindingModel model) { diff --git a/Shipyard/ShipyardDataBaseImplement/Models/Order.cs b/Shipyard/ShipyardDataBaseImplement/Models/Order.cs index 8be5147..b836e4c 100644 --- a/Shipyard/ShipyardDataBaseImplement/Models/Order.cs +++ b/Shipyard/ShipyardDataBaseImplement/Models/Order.cs @@ -3,25 +3,36 @@ using ShipyardContracts.ViewModels; using ShipyardDataModels.Enums; using ShipyardDataModels.Models; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace ShipyardDataBaseImplement.Models { + [DataContract] public class Order : IOrderModel { [Required] + [DataMember] public int ShipId { get; set; } [Required] + [DataMember] public int ClientId { get; set; } - public int? ImplementerId { get; set; } + [DataMember] + public int? ImplementerId { get; set; } [Required] + [DataMember] public int Count { get; set; } [Required] + [DataMember] public double Sum { get; set; } [Required] + [DataMember] public OrderStatus Status { get; set; } [Required] + [DataMember] public DateTime DateCreate { get; set; } + [DataMember] public DateTime? DateImplement { get; set; } + [DataMember] public int Id { get; set; } public virtual Ship Ship { get; set; } public virtual Client Client { get; set; } diff --git a/Shipyard/ShipyardDataBaseImplement/Models/Ship.cs b/Shipyard/ShipyardDataBaseImplement/Models/Ship.cs index 63c008e..1fa85f9 100644 --- a/Shipyard/ShipyardDataBaseImplement/Models/Ship.cs +++ b/Shipyard/ShipyardDataBaseImplement/Models/Ship.cs @@ -3,18 +3,24 @@ using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace ShipyardDataBaseImplement.Models { + [DataContract] public class Ship : IShipModel { + [DataMember] public int Id { get; set; } [Required] + [DataMember] public string ShipName { get; set; } = string.Empty; [Required] + [DataMember] public double Price { get; set; } private Dictionary? _shipDetails = null; [NotMapped] + [DataMember] public Dictionary ShipDetails { get diff --git a/Shipyard/ShipyardDataBaseImplement/ShipyardDataBaseImplement.csproj b/Shipyard/ShipyardDataBaseImplement/ShipyardDataBaseImplement.csproj index 0f6a6a4..b15380f 100644 --- a/Shipyard/ShipyardDataBaseImplement/ShipyardDataBaseImplement.csproj +++ b/Shipyard/ShipyardDataBaseImplement/ShipyardDataBaseImplement.csproj @@ -24,4 +24,8 @@ + + + + diff --git a/Shipyard/ShipyardDataModels/Models/IMessageInfoModel.cs b/Shipyard/ShipyardDataModels/Models/IMessageInfoModel.cs index f56a690..6398bb6 100644 --- a/Shipyard/ShipyardDataModels/Models/IMessageInfoModel.cs +++ b/Shipyard/ShipyardDataModels/Models/IMessageInfoModel.cs @@ -1,6 +1,6 @@ namespace ShipyardDataModels.Models { - public interface IMessageInfoModel + public interface IMessageInfoModel : IId { string MessageId { get; } diff --git a/Shipyard/ShipyardFileImplement/FileImplementationExtension.cs b/Shipyard/ShipyardFileImplement/FileImplementationExtension.cs new file mode 100644 index 0000000..381f062 --- /dev/null +++ b/Shipyard/ShipyardFileImplement/FileImplementationExtension.cs @@ -0,0 +1,22 @@ +using ShipyardContracts.DI; +using ShipyardContracts.StoragesContracts; +using ShipyardFileImplement.Implements; + +namespace ShipyardFileImplement +{ + public class FileImplementationExtension : IImplementationExtension + { + public int Priority => 1; + + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardFileImplement/Implements/BackUpInfo.cs b/Shipyard/ShipyardFileImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..d284146 --- /dev/null +++ b/Shipyard/ShipyardFileImplement/Implements/BackUpInfo.cs @@ -0,0 +1,29 @@ +using ShipyardContracts.StoragesContracts; + +namespace ShipyardFileImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + var source = DataFileSingleton.GetInstance(); + return (List?)source.GetType().GetProperties() + .FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == typeof(T)) + ?.GetValue(source); + } + + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + var assembly = typeof(BackUpInfo).Assembly; + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsClass && type.GetInterface(modelInterfaceName) != null) + { + return type; + } + } + return null; + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardFileImplement/Models/Client.cs b/Shipyard/ShipyardFileImplement/Models/Client.cs index 935ef0a..e640be4 100644 --- a/Shipyard/ShipyardFileImplement/Models/Client.cs +++ b/Shipyard/ShipyardFileImplement/Models/Client.cs @@ -1,15 +1,21 @@ using ShipyardContracts.BindingModels; using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace ShipyardFileImplement.Models { + [DataContract] public class Client : IClientModel { + [DataMember] public int Id { get; set; } + [DataMember] public string ClientFIO { get; set; } = string.Empty; + [DataMember] public string Email { get; set; } = string.Empty; + [DataMember] public string Password { get; set; } = string.Empty; public static Client? Create(ClientBindingModel model) { diff --git a/Shipyard/ShipyardFileImplement/Models/Detail.cs b/Shipyard/ShipyardFileImplement/Models/Detail.cs index 97bb6be..86df017 100644 --- a/Shipyard/ShipyardFileImplement/Models/Detail.cs +++ b/Shipyard/ShipyardFileImplement/Models/Detail.cs @@ -1,14 +1,19 @@ using ShipyardContracts.BindingModels; using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace ShipyardFileImplement.Models { + [DataContract] public class Detail : IDetailModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string DetailName { get; private set; } = string.Empty; + [DataMember] public double Cost { get; set; } public static Detail? Create(DetailBindingModel model) { diff --git a/Shipyard/ShipyardFileImplement/Models/Implementer.cs b/Shipyard/ShipyardFileImplement/Models/Implementer.cs index 57ac58d..c0dc658 100644 --- a/Shipyard/ShipyardFileImplement/Models/Implementer.cs +++ b/Shipyard/ShipyardFileImplement/Models/Implementer.cs @@ -1,21 +1,24 @@ using ShipyardContracts.BindingModels; using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace ShipyardFileImplement.Models { - public class Implementer : IImplementerModel + [DataContract] + public class Implementer : IImplementerModel { - public string ImplementerFIO { get; set; } = String.Empty; - - public string Password { get; set; } = String.Empty; - - public int WorkExperience { get; set; } - - public int Qualification { get; set; } - - 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; } + [DataMember] + public int Id { get; set; } public static Implementer? Create(ImplementerBindingModel? model) { diff --git a/Shipyard/ShipyardFileImplement/Models/Message.cs b/Shipyard/ShipyardFileImplement/Models/Message.cs index 0c304df..6447174 100644 --- a/Shipyard/ShipyardFileImplement/Models/Message.cs +++ b/Shipyard/ShipyardFileImplement/Models/Message.cs @@ -1,23 +1,27 @@ using ShipyardContracts.BindingModels; using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace ShipyardFileImplement.Models { + [DataContract] public class Message : IMessageInfoModel { + [DataMember] public string MessageId { get; private set; } = string.Empty; - + [DataMember] public int? ClientId { get; private set; } - + [DataMember] public string SenderName { get; private set; } = string.Empty; - + [DataMember] public DateTime DateDelivery { get; private set; } = DateTime.Now; - + [DataMember] public string Subject { get; private set; } = string.Empty; - + [DataMember] public string Body { get; private set; } = string.Empty; + public int Id => throw new NotImplementedException(); public static Message? Create(MessageInfoBindingModel model) { if (model == null) diff --git a/Shipyard/ShipyardFileImplement/Models/Order.cs b/Shipyard/ShipyardFileImplement/Models/Order.cs index b109045..e511ba6 100644 --- a/Shipyard/ShipyardFileImplement/Models/Order.cs +++ b/Shipyard/ShipyardFileImplement/Models/Order.cs @@ -2,20 +2,31 @@ using ShipyardContracts.ViewModels; using ShipyardDataModels.Enums; using ShipyardDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace ShipyardFileImplement.Models { + [DataContract] public class Order : IOrderModel { + [DataMember] public int Id { get; private set; } + [DataMember] public int ShipId { 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; } + [DataMember] public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; + [DataMember] public DateTime DateCreate { get; private set; } = DateTime.Now; + [DataMember] public DateTime? DateImplement { get; private set; } public static Order? Create(OrderBindingModel? model) { diff --git a/Shipyard/ShipyardFileImplement/Models/Ship.cs b/Shipyard/ShipyardFileImplement/Models/Ship.cs index 835acb2..279f92a 100644 --- a/Shipyard/ShipyardFileImplement/Models/Ship.cs +++ b/Shipyard/ShipyardFileImplement/Models/Ship.cs @@ -1,17 +1,23 @@ using ShipyardContracts.BindingModels; using ShipyardContracts.ViewModels; using ShipyardDataModels.Models; +using System.Runtime.Serialization; using System.Xml.Linq; namespace ShipyardFileImplement.Models { + [DataContract] public class Ship : IShipModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string ShipName { get; private set; } = string.Empty; + [DataMember] public double Price { get; private set; } public Dictionary Details { get; private set; } = new(); private Dictionary? _shipDetails = null; + [DataMember] public Dictionary ShipDetails { get diff --git a/Shipyard/ShipyardFileImplement/ShipyardFileImplement.csproj b/Shipyard/ShipyardFileImplement/ShipyardFileImplement.csproj index 6f16bc4..4456689 100644 --- a/Shipyard/ShipyardFileImplement/ShipyardFileImplement.csproj +++ b/Shipyard/ShipyardFileImplement/ShipyardFileImplement.csproj @@ -10,5 +10,8 @@ - + + + + diff --git a/Shipyard/ShipyardListImplement/Implements/BackUpInfo.cs b/Shipyard/ShipyardListImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..3b4ceca --- /dev/null +++ b/Shipyard/ShipyardListImplement/Implements/BackUpInfo.cs @@ -0,0 +1,17 @@ +using ShipyardContracts.StoragesContracts; + +namespace ShipyardListImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + throw new NotImplementedException(); + } + + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardListImplement/ListImplementationExtension.cs b/Shipyard/ShipyardListImplement/ListImplementationExtension.cs new file mode 100644 index 0000000..22e6409 --- /dev/null +++ b/Shipyard/ShipyardListImplement/ListImplementationExtension.cs @@ -0,0 +1,22 @@ +using ShipyardContracts.DI; +using ShipyardContracts.StoragesContracts; +using ShipyardListImplement.Implements; + +namespace ShipyardListImplement +{ + public class ListImplementationExtension : IImplementationExtension + { + public int Priority => 0; + + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardListImplement/Models/Message.cs b/Shipyard/ShipyardListImplement/Models/Message.cs index 573aab2..80cfe5f 100644 --- a/Shipyard/ShipyardListImplement/Models/Message.cs +++ b/Shipyard/ShipyardListImplement/Models/Message.cs @@ -17,7 +17,7 @@ namespace ShipyardListImplement.Models public string Subject { get; private set; } = string.Empty; public string Body { get; private set; } = string.Empty; - + public int Id => throw new NotImplementedException(); public static Message? Create(MessageInfoBindingModel model) { if (model == null) diff --git a/Shipyard/ShipyardListImplement/ShipyardListImplement.csproj b/Shipyard/ShipyardListImplement/ShipyardListImplement.csproj index 6f16bc4..ffe6e7c 100644 --- a/Shipyard/ShipyardListImplement/ShipyardListImplement.csproj +++ b/Shipyard/ShipyardListImplement/ShipyardListImplement.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/Shipyard/ShipyardView/DataGridViewExtension.cs b/Shipyard/ShipyardView/DataGridViewExtension.cs new file mode 100644 index 0000000..8241c92 --- /dev/null +++ b/Shipyard/ShipyardView/DataGridViewExtension.cs @@ -0,0 +1,45 @@ +using ShipyardContracts.Attributes; +namespace ShipyardView +{ + internal 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; + } + } + } + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardView/FormClients.cs b/Shipyard/ShipyardView/FormClients.cs index 7faecb0..d8a39ba 100644 --- a/Shipyard/ShipyardView/FormClients.cs +++ b/Shipyard/ShipyardView/FormClients.cs @@ -27,13 +27,7 @@ namespace ShipyardView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка клиентов"); } catch (Exception ex) diff --git a/Shipyard/ShipyardView/FormDetails.Designer.cs b/Shipyard/ShipyardView/FormDetails.Designer.cs index de4f31b..1d33687 100644 --- a/Shipyard/ShipyardView/FormDetails.Designer.cs +++ b/Shipyard/ShipyardView/FormDetails.Designer.cs @@ -42,6 +42,7 @@ dataGridView.AllowUserToDeleteRows = false; dataGridView.AllowUserToResizeColumns = false; dataGridView.AllowUserToResizeRows = false; + dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; dataGridView.Location = new Point(-2, -1); dataGridView.Name = "dataGridView"; diff --git a/Shipyard/ShipyardView/FormDetails.cs b/Shipyard/ShipyardView/FormDetails.cs index f073a42..f8be0d3 100644 --- a/Shipyard/ShipyardView/FormDetails.cs +++ b/Shipyard/ShipyardView/FormDetails.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using ShipyardContracts.BindingModels; using ShipyardContracts.BusinessLogicsContracts; +using ShipyardContracts.DI; using System.Windows.Forms; namespace ShipyardView @@ -24,13 +25,7 @@ namespace ShipyardView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["DetailName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка деталей"); } catch (Exception ex) @@ -42,13 +37,10 @@ namespace ShipyardView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormDetail)); - if (service is FormDetail form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - if (form.ShowDialog() == DialogResult.OK) - { LoadData(); - } } } @@ -56,14 +48,11 @@ namespace ShipyardView { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormDetail)); - if (service is FormDetail 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(); - } } } } diff --git a/Shipyard/ShipyardView/FormImplementers.cs b/Shipyard/ShipyardView/FormImplementers.cs index c084087..e6abdd5 100644 --- a/Shipyard/ShipyardView/FormImplementers.cs +++ b/Shipyard/ShipyardView/FormImplementers.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using ShipyardContracts.BindingModels; using ShipyardContracts.BusinessLogicsContracts; +using ShipyardContracts.DI; using System.Windows.Forms; namespace ShipyardView @@ -24,17 +25,8 @@ namespace ShipyardView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["Password"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["WorkExperience"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["Qualification"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } - _logger.LogInformation("Загрузка исполнителей"); + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка исполнителей"); } catch (Exception ex) { @@ -45,13 +37,10 @@ namespace ShipyardView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); - if (service is FormImplementer form) - { - if (form.ShowDialog() == DialogResult.OK) - { + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) + { LoadData(); - } } } @@ -59,14 +48,11 @@ namespace ShipyardView { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); - if (service is FormImplementer form) - { - form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - if (form.ShowDialog() == DialogResult.OK) - { + var form = DependencyManager.Instance.Resolve(); + form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + if (form.ShowDialog() == DialogResult.OK) + { LoadData(); - } } } } diff --git a/Shipyard/ShipyardView/FormMails.cs b/Shipyard/ShipyardView/FormMails.cs index aaeddc3..806c925 100644 --- a/Shipyard/ShipyardView/FormMails.cs +++ b/Shipyard/ShipyardView/FormMails.cs @@ -20,14 +20,7 @@ namespace ShipyardView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["MessageId"].Visible = false; - dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка писем"); } catch (Exception ex) diff --git a/Shipyard/ShipyardView/FormMain.Designer.cs b/Shipyard/ShipyardView/FormMain.Designer.cs index 9e19b1c..728a844 100644 --- a/Shipyard/ShipyardView/FormMain.Designer.cs +++ b/Shipyard/ShipyardView/FormMain.Designer.cs @@ -45,6 +45,7 @@ buttonCreateOrder = new Button(); buttonIssue = new Button(); buttonRefresh = new Button(); + создатьБекапToolStripMenuItem = new ToolStripButton(); toolStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); SuspendLayout(); @@ -52,7 +53,7 @@ // toolStrip // toolStrip.ImageScalingSize = new Size(20, 20); - toolStrip.Items.AddRange(new ToolStripItem[] { toolStripMenu, отчетыToolStripMenuItem, startWorkToolStripMenuItem, mailsToolStripMenuItem }); + toolStrip.Items.AddRange(new ToolStripItem[] { toolStripMenu, отчетыToolStripMenuItem, startWorkToolStripMenuItem, mailsToolStripMenuItem, создатьБекапToolStripMenuItem }); toolStrip.Location = new Point(0, 0); toolStrip.Name = "toolStrip"; toolStrip.Size = new Size(1522, 27); @@ -195,6 +196,16 @@ buttonRefresh.UseVisualStyleBackColor = true; buttonRefresh.Click += ButtonRef_Click; // + // создатьБекапToolStripMenuItem + // + создатьБекапToolStripMenuItem.DisplayStyle = ToolStripItemDisplayStyle.Text; + создатьБекапToolStripMenuItem.Image = (Image)resources.GetObject("создатьБекапToolStripMenuItem.Image"); + создатьБекапToolStripMenuItem.ImageTransparentColor = Color.Magenta; + создатьБекапToolStripMenuItem.Name = "создатьБекапToolStripMenuItem"; + создатьБекапToolStripMenuItem.Size = new Size(113, 24); + создатьБекапToolStripMenuItem.Text = "Создать бекап"; + создатьБекапToolStripMenuItem.Click += создатьБекапToolStripMenuItem_Click; + // // FormMain // AutoScaleDimensions = new SizeF(8F, 20F); @@ -233,5 +244,6 @@ private ToolStripMenuItem исполнителиToolStripMenuItem; private ToolStripButton startWorkToolStripMenuItem; private ToolStripButton mailsToolStripMenuItem; + private ToolStripButton создатьБекапToolStripMenuItem; } } \ No newline at end of file diff --git a/Shipyard/ShipyardView/FormMain.cs b/Shipyard/ShipyardView/FormMain.cs index fe55b01..da1963f 100644 --- a/Shipyard/ShipyardView/FormMain.cs +++ b/Shipyard/ShipyardView/FormMain.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using ShipyardContracts.BindingModels; using ShipyardContracts.BusinessLogicsContracts; +using ShipyardContracts.DI; using ShipyardDataModels.Enums; using ShipyardView; using System.Windows.Forms; @@ -13,15 +14,17 @@ namespace ShipyardView private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; private readonly IWorkProcess _workProcess; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) - { - InitializeComponent(); - _logger = logger; - _orderLogic = orderLogic; - _reportLogic = reportLogic; - _workProcess = workProcess; - } - private void FormMain_Load(object sender, EventArgs e) + private readonly IBackUpLogic _backUpLogic; + public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess, IBackUpLogic backUpLogic) + { + InitializeComponent(); + _logger = logger; + _orderLogic = orderLogic; + _reportLogic = reportLogic; + _workProcess = workProcess; + _backUpLogic = backUpLogic; + } + private void FormMain_Load(object sender, EventArgs e) { LoadData(); } @@ -29,15 +32,8 @@ namespace ShipyardView { try { - var list = _orderLogic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["ShipId"].Visible = false; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["ImplementerId"].Visible = false; - } - _logger.LogInformation("Загрузка заказов"); + dataGridView.FillAndConfigGrid(_orderLogic.ReadList(null)); + _logger.LogInformation("Загрузка заказов"); } catch (Exception ex) { @@ -47,29 +43,20 @@ namespace ShipyardView } private void ДеталиToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormDetails)); - if (service is FormDetails form) - { - form.ShowDialog(); - } - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); + } private void КораблиToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormShips)); - if (service is FormShips 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 ButtonIssuedOrder_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) @@ -109,50 +96,61 @@ namespace ShipyardView private void shipDetailsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportShipDetails)); - if (service is FormReportShipDetails form) - { - form.ShowDialog(); - } - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); + } private void ordersToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders)); - if (service is FormReportOrders form) - { - form.ShowDialog(); - } - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); + } private void 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 mailsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormMails)); - if (service is FormMails form) - { - form.ShowDialog(); - } + var form = DependencyManager.Instance.Resolve(); + form.ShowDialog(); } private void ImplementerToolStripMenuItem_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 создатьБекапToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + if (_backUpLogic != null) + { + var fbd = new FolderBrowserDialog(); + if (fbd.ShowDialog() == DialogResult.OK) + { + _backUpLogic.CreateBackUp(new BackUpSaveBinidngModel + { + FolderName = fbd.SelectedPath + }); + MessageBox.Show("Бекап создан", "Сообщение", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + } } \ No newline at end of file diff --git a/Shipyard/ShipyardView/FormMain.resx b/Shipyard/ShipyardView/FormMain.resx index 481384a..4bcb328 100644 --- a/Shipyard/ShipyardView/FormMain.resx +++ b/Shipyard/ShipyardView/FormMain.resx @@ -163,6 +163,17 @@ U87f4aUApcXhnrI9Jzg/laQKFntXlHM+lSQK5psL5fvbp/JvJLGCQqmSWM5JkiCT84igXGtSrruKLQ0T luAdmZxHBG37FFuWBC/j5XKOmX8WAH7rcI6ZMffPgjQwN2bXJgDo/COBTpjneQ2dML0PY3cISreGe8HM qgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAEISURBVEhL3ZErDsJAGIR7DlA47oArV8CDR9RiSDAQPBcA + Qx1BgUMQBEk1ooJAKE0I4Wlqf5gmu1n6oqW7hiZfthkx33aqeZ5HKvEFpmmSYRhSQScXINB1XSroDAke + 96cUpAmupyPZsx7Z8x4drAnPpQmsgU7LdoHDJNIEYjnAlyBXJ3jPhVyaYLca8nLMhX+CPJXAOT+ouTj5 + p5in4asApdWpS8XRwT+zShIFG/fOyxlZJbGC9f5G5bHzUf6LJFJQqTViyxlxEmRiHhLUW10qDbeRpUGC + ErwjE/OQoG9dIsviYGWsXMwxc24BYLcO5pgZc+cWJIG5MbsyAUDnHwlUAkFHJZraR9NeMVq3zi+WF/0A + AAAASUVORK5CYII= \ No newline at end of file diff --git a/Shipyard/ShipyardView/FormShip.cs b/Shipyard/ShipyardView/FormShip.cs index ebfe77d..22bba4c 100644 --- a/Shipyard/ShipyardView/FormShip.cs +++ b/Shipyard/ShipyardView/FormShip.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using ShipyardContracts.BindingModels; using ShipyardContracts.BusinessLogicsContracts; +using ShipyardContracts.DI; using ShipyardContracts.SearchModels; using ShipyardDataModels.Models; using System.Windows.Forms; @@ -75,26 +76,23 @@ namespace ShipyardView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormShipDetail)); - if (service is FormShipDetail form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - if (form.ShowDialog() == DialogResult.OK) + if (form.DetailModel == null) { - if (form.DetailModel == null) - { - return; - } - _logger.LogInformation("Добавление новой детали:{ DetailName} - { Count}", form.DetailModel.DetailName, form.Count); - if (_shipDetails.ContainsKey(form.Id)) - { - _shipDetails[form.Id] = (form.DetailModel, form.Count); - } - else - { - _shipDetails.Add(form.Id, (form.DetailModel, form.Count)); - } - LoadData(); + return; } + _logger.LogInformation("Добавление новой детали:{ DetailName} - { Count}", form.DetailModel.DetailName, form.Count); + if (_shipDetails.ContainsKey(form.Id)) + { + _shipDetails[form.Id] = (form.DetailModel, form.Count); + } + else + { + _shipDetails.Add(form.Id, (form.DetailModel, form.Count)); + } + LoadData(); } } @@ -102,22 +100,19 @@ namespace ShipyardView { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormShipDetail)); - if (service is FormShipDetail form) + var form = DependencyManager.Instance.Resolve(); + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); + form.Id = id; + form.Count = _shipDetails[id].Item2; + if (form.ShowDialog() == DialogResult.OK) { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value); - form.Id = id; - form.Count = _shipDetails[id].Item2; - if (form.ShowDialog() == DialogResult.OK) + if (form.DetailModel == null) { - if (form.DetailModel == null) - { - return; - } - _logger.LogInformation("Изменение детали: { DetailName} - { Count}", form.DetailModel.DetailName, form.Count); - _shipDetails[form.Id] = (form.DetailModel, form.Count); - LoadData(); + return; } + _logger.LogInformation("Изменение детали: { DetailName} - { Count}", form.DetailModel.DetailName, form.Count); + _shipDetails[form.Id] = (form.DetailModel, form.Count); + LoadData(); } } } diff --git a/Shipyard/ShipyardView/FormShips.cs b/Shipyard/ShipyardView/FormShips.cs index 512ce12..873fc37 100644 --- a/Shipyard/ShipyardView/FormShips.cs +++ b/Shipyard/ShipyardView/FormShips.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using ShipyardContracts.BindingModels; using ShipyardContracts.BusinessLogicsContracts; +using ShipyardContracts.DI; using System.Windows.Forms; namespace ShipyardView @@ -24,14 +25,7 @@ namespace ShipyardView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ShipName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["ShipDetails"].Visible = false; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка кораблей"); } catch (Exception ex) @@ -43,13 +37,10 @@ namespace ShipyardView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormShip)); - if (service is FormShip form) + var form = DependencyManager.Instance.Resolve(); + if (form.ShowDialog() == DialogResult.OK) { - if (form.ShowDialog() == DialogResult.OK) - { LoadData(); - } } } @@ -57,14 +48,11 @@ namespace ShipyardView { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormShip)); - if (service is FormShip 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(); - } } } } diff --git a/Shipyard/ShipyardView/Program.cs b/Shipyard/ShipyardView/Program.cs index ea47b1e..574dc2e 100644 --- a/Shipyard/ShipyardView/Program.cs +++ b/Shipyard/ShipyardView/Program.cs @@ -9,14 +9,14 @@ using ShipyardBusinessLogic.OfficePackage.Implements; using ShipyardBusinessLogic.OfficePackage; using NLog.Extensions.Logging; using Microsoft.Extensions.Logging; +using ShipyardBusinessLogic; +using ShipyardContracts.DI; namespace ShipyardView { internal static class Program { - private static ServiceProvider? _serviceProvider; - public static ServiceProvider? ServiceProvider => _serviceProvider; /// /// The main entry point for the application. /// @@ -24,12 +24,10 @@ namespace ShipyardView 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, @@ -44,50 +42,46 @@ namespace ShipyardView } catch (Exception ex) { - var logger = _serviceProvider.GetService(); + var logger = DependencyManager.Instance.Resolve(); logger?.LogError(ex, " "); } - Application.Run(_serviceProvider.GetRequiredService()); + Application.Run(DependencyManager.Instance.Resolve()); } - private static void ConfigureServices(ServiceCollection services) + private static void InitDependency() { - services.AddLogging(option => + DependencyManager.InitDependency(); + + DependencyManager.Instance.AddLogging(option => { option.AddNLog("NLog.config"); }); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + 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(true); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); } - private static void MailCheck(object obj) => ServiceProvider?.GetService()?.MailCheck(); + private static void MailCheck(object obj) => DependencyManager.Instance?.Resolve()?.MailCheck(); } - } \ No newline at end of file diff --git a/Shipyard/ShipyardView/ShipyardView.csproj b/Shipyard/ShipyardView/ShipyardView.csproj index 706831f..c128424 100644 --- a/Shipyard/ShipyardView/ShipyardView.csproj +++ b/Shipyard/ShipyardView/ShipyardView.csproj @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - +