From bd6795267977fa36b3a08c4b14692944303c2361 Mon Sep 17 00:00:00 2001 From: devil_1nc Date: Sat, 3 Jun 2023 04:03:28 +0400 Subject: [PATCH] attributes + DI + view models --- ...stractSoftwareInstallationContracts.csproj | 6 ++ .../Attributes/ColumnAttribute.cs | 27 ++++++++ .../Attributes/GridViewAutoSize.cs | 20 ++++++ .../DI/DependencyManager.cs | 66 +++++++++++++++++++ .../DI/IDependencyContainer.cs | 40 +++++++++++ .../DI/IImplementationExtension.cs | 17 +++++ .../DI/ServiceDependencyContainer.cs | 62 +++++++++++++++++ .../DI/ServiceProviderLoader.cs | 52 +++++++++++++++ .../DI/UnityDependencyContainer.cs | 44 +++++++++++++ .../ViewModels/ClientViewModel.cs | 19 ++++-- .../ViewModels/ImplementerViewModel.cs | 12 ++-- .../ViewModels/MessageInfoViewModel.cs | 34 ++++++---- .../ViewModels/OrderViewModel.cs | 24 ++++--- .../ViewModels/PackageViewModel.cs | 7 +- .../ViewModels/SoftwareViewModel.cs | 6 +- 15 files changed, 398 insertions(+), 38 deletions(-) create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/ColumnAttribute.cs create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/GridViewAutoSize.cs create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/DependencyManager.cs create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/IDependencyContainer.cs create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/IImplementationExtension.cs create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/ServiceDependencyContainer.cs create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/ServiceProviderLoader.cs create mode 100644 SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/UnityDependencyContainer.cs diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/AbstractSoftwareInstallationContracts.csproj b/SoftwareInstallation/AbstractSoftwareInstallationContracts/AbstractSoftwareInstallationContracts.csproj index e427344..ac59634 100644 --- a/SoftwareInstallation/AbstractSoftwareInstallationContracts/AbstractSoftwareInstallationContracts.csproj +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/AbstractSoftwareInstallationContracts.csproj @@ -6,6 +6,12 @@ enable + + + + + + diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/ColumnAttribute.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..d5aafc0 --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractSoftwareInstallationContracts.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/SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/GridViewAutoSize.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..1f9aed2 --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractSoftwareInstallationContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + None = 1, + ColumnHeader = 2, + AllCellsExceptHeader = 4, + AllCells = 6, + DisplayedCellsExceptHeader = 8, + DisplayedCells = 10, + Fill = 16 + } +} diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/DependencyManager.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..c8348ba --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/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 AbstractSoftwareInstallationContracts.DI +{ + public class DependencyManager + { + private readonly IDependencyContainer _dependencyManager; + + private static DependencyManager? _manager; + + private static readonly object _locjObject = new(); + + private DependencyManager() + { + _dependencyManager = new UnityDependencyContainer(); + } + + public static DependencyManager Instance { get { if (_manager == null) { lock (_locjObject) { _manager = new DependencyManager(); } } return _manager; } } + + /// + /// Иницализация библиотек, в которых идут установки зависомстей + /// + public static void InitDependency() + { + var ext = ServiceProviderLoader.GetImplementationExtensions(); + if (ext == null) + { + throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям"); + } + // регистрируем зависимости + ext.RegisterServices(); + } + + /// + /// Регистрация логгера + /// + /// + public void AddLogging(Action configure) => _dependencyManager.AddLogging(configure); + + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where U : class, T where T : class => _dependencyManager.RegisterType(isSingle); + + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where T : class => _dependencyManager.RegisterType(isSingle); + + /// + /// Получение класса со всеми зависмостями + /// + /// + /// + public T Resolve() => _dependencyManager.Resolve(); + } +} diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/IDependencyContainer.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..74b56d0 --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/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 AbstractSoftwareInstallationContracts.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/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/IImplementationExtension.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..819241d --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/IImplementationExtension.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractSoftwareInstallationContracts.DI +{ + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/ServiceDependencyContainer.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..130988d --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/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 AbstractSoftwareInstallationContracts.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/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/ServiceProviderLoader.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..8390f2e --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace AbstractSoftwareInstallationContracts.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/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/UnityDependencyContainer.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..ac34eb0 --- /dev/null +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,44 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unity; +using Unity.Lifetime; +using Unity.Microsoft.Logging; + +namespace AbstractSoftwareInstallationContracts.DI +{ + public class UnityDependencyContainer : IDependencyContainer + { + private readonly IUnityContainer _container; + + public UnityDependencyContainer() + { + _container = new UnityContainer(); + } + + public void AddLogging(Action configure) + { + var factory = LoggerFactory.Create(configure); + _container.AddExtension(new LoggingExtension(factory)); + } + + public void RegisterType(bool isSingle) where T : class + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + + } + + public T Resolve() + { + return _container.Resolve(); + } + + void IDependencyContainer.RegisterType(bool isSingle) + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + } + } +} diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ClientViewModel.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ClientViewModel.cs index df8c8a1..e0f8dd1 100644 --- a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ClientViewModel.cs +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ClientViewModel.cs @@ -1,4 +1,5 @@ -using AbstractSoftwareInstallationDataModels.Models; +using AbstractSoftwareInstallationContracts.Attributes; +using AbstractSoftwareInstallationDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,13 +11,17 @@ namespace AbstractSoftwareInstallationContracts.ViewModels { public class ClientViewModel : IClientModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО клиента")] - public string ClientFIO { get; set; }= string.Empty; - [DisplayName("Логин (эл. почта)")] - public string Email { get; set; }= string.Empty; - [DisplayName("Пароль")] - public string Password { get; set; }= string.Empty; + + [Column(title: "ФИО клиента", width: 150)] + public string ClientFIO { get; set; } = string.Empty; + + [Column(title: "Логин (эл.почта)", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string Email { get; set; } = string.Empty; + + [Column(title: "Пароль", width: 150)] + public string Password { get; set; } = string.Empty; } } diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ImplementerViewModel.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ImplementerViewModel.cs index 2415654..ded6ae9 100644 --- a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ImplementerViewModel.cs +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/ImplementerViewModel.cs @@ -1,4 +1,5 @@ -using AbstractSoftwareInstallationDataModels.Models; +using AbstractSoftwareInstallationContracts.Attributes; +using AbstractSoftwareInstallationDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,18 +11,19 @@ namespace AbstractSoftwareInstallationContracts.ViewModels { public class ImplementerViewModel : IImplementerModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО")] + [Column("ФИО", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column("Пароль", width: 200)] public string Password { get; set; } = string.Empty; - [DisplayName("Опыт работы")] + [Column("Трудовой стаж", width: 200)] public int WorkExperience { get; set; } - [DisplayName("Квалификация")] + [Column("Квалификация", width: 200)] public int Qualification { get; set; } } } diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/MessageInfoViewModel.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/MessageInfoViewModel.cs index 8a3fa1c..9c05be8 100644 --- a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/MessageInfoViewModel.cs +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/MessageInfoViewModel.cs @@ -1,4 +1,5 @@ -using AbstractSoftwareInstallationDataModels.Models; +using AbstractSoftwareInstallationContracts.Attributes; +using AbstractSoftwareInstallationDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,16 +11,25 @@ namespace AbstractSoftwareInstallationContracts.ViewModels { public class MessageInfoViewModel : IMessageInfoModel { - public string MessageId { get; set; } = string.Empty; + [Column(visible: false)] + public string MessageId { get; set; } = string.Empty; - public int? ClientId { get; set; } - [DisplayName("Отправитель")] - public string SenderName { get; set; } = string.Empty; - [DisplayName("Дата письма")] - public DateTime DateDelivery { get; set; } - [DisplayName("Заголовок")] - public string Subject { get; set; } = string.Empty; - [DisplayName("Текст")] - public string Body { get; set; } = string.Empty; - } + [Column(visible: false)] + public int? ClientId { get; set; } + + [Column("Отправитель", gridViewAutoSize: GridViewAutoSize.DisplayedCells, isUseAutoSize: true)] + public string SenderName { get; set; } = string.Empty; + + [Column("Дата письма", width: 100)] + public DateTime DateDelivery { get; set; } + + [Column("Заголовок", width: 150)] + public string Subject { get; set; } = string.Empty; + + [Column("Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] + public string Body { get; set; } = string.Empty; + + [Column(visible: false)] + public int Id => throw new NotImplementedException(); + } } diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/OrderViewModel.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/OrderViewModel.cs index a673326..98f6c46 100644 --- a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/OrderViewModel.cs +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/OrderViewModel.cs @@ -6,33 +6,37 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using AbstractSoftwareInstallationContracts.Attributes; namespace AbstractSoftwareInstallationContracts.ViewModels { public class OrderViewModel : IOrderModel { - - [DisplayName("Номер заказа")] + + [Column("Номер", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int Id { get; set; } + [Column(visible: false)] public int PackageId { get; set; } + [Column(visible: false)] public int ClientId { get; set; } + [Column(visible: false)] public int? ImplementerId { get; set; } - [DisplayName("Пакет")] + [Column("Пакет", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string PackageName { get; set; } = string.Empty; - [DisplayName("Логин клиента")] + [Column("Почта клиента", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string Email { get; set; } = string.Empty; - [DisplayName("Исполнитель")] + [Column("ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Количество")] + [Column("Количество", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int Count { get; set; } - [DisplayName("Сумма")] + [Column("Сумма", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public double Sum { get; set; } - [DisplayName("Статус")] + [Column("Статус", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; - [DisplayName("Дата создания")] + [Column("Дата создания", width: 100)] public DateTime DateCreate { get; set; } = DateTime.Now; - [DisplayName("Дата выдачи")] + [Column("Дата выдачи", width: 100)] public DateTime? DateImplement { get; set; } } } diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/PackageViewModel.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/PackageViewModel.cs index 8b5a248..96a47d1 100644 --- a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/PackageViewModel.cs +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/PackageViewModel.cs @@ -5,16 +5,19 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using AbstractSoftwareInstallationContracts.Attributes; namespace AbstractSoftwareInstallationContracts.ViewModels { public class PackageViewModel : IPackageModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Имя пакета")] + [Column("Имя пакета", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string PackageName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column("Цена", width: 100)] public double Price { get; set; } + [Column(visible: false)] public Dictionary PackageSoftware { get; diff --git a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/SoftwareViewModel.cs b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/SoftwareViewModel.cs index b8ed809..092d32d 100644 --- a/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/SoftwareViewModel.cs +++ b/SoftwareInstallation/AbstractSoftwareInstallationContracts/ViewModels/SoftwareViewModel.cs @@ -5,15 +5,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using AbstractSoftwareInstallationContracts.Attributes; namespace AbstractSoftwareInstallationContracts.ViewModels { public class SoftwareViewModel : ISoftwareModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Название")] + [Column("Название ПО", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string SoftwareName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column("Цена", width: 100)] public double Cost { get; set; } } }