diff --git a/Excavator/.editorconfig b/Excavator/.editorconfig new file mode 100644 index 0000000..91c8707 --- /dev/null +++ b/Excavator/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# IDE0058: Значение выражения никогда не используется +csharp_style_unused_value_expression_statement_preference = discard_variable diff --git a/Excavator/Excavator.sln b/Excavator/Excavator.sln index 328269f..f6d32b9 100644 --- a/Excavator/Excavator.sln +++ b/Excavator/Excavator.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34330.188 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Excavator", "Excavator\Excavator.csproj", "{DD2A9FE6-2F74-4387-9318-59AE715EBA73}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Excavator", "Excavator\Excavator.csproj", "{DD2A9FE6-2F74-4387-9318-59AE715EBA73}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Excavator/Excavator/CollectionGenericObjects/AbstractCompany.cs b/Excavator/Excavator/CollectionGenericObjects/AbstractCompany.cs index 9991527..ce941c9 100644 --- a/Excavator/Excavator/CollectionGenericObjects/AbstractCompany.cs +++ b/Excavator/Excavator/CollectionGenericObjects/AbstractCompany.cs @@ -1,4 +1,5 @@ using Excavator.Drawnings; +using Excavator.Exceptions; namespace Excavator.CollectionGenericObjects; @@ -95,14 +96,19 @@ public abstract class AbstractCompany Bitmap bitmap = new(_pictureWidth, _pictureHeight); Graphics graphics = Graphics.FromImage(bitmap); DrawBackgound(graphics); - SetObjectsPosition(); for (int i = 0; i < (_collection?.Count ?? 0); ++i) { - DrawningTrackedVehicle? obj = _collection?.Get(i); - obj?.DrawTransport(graphics); + try + { + DrawningTrackedVehicle? obj = _collection?.Get(i); + obj?.DrawTransport(graphics); + } + catch (ObjectNotFoundException) + { + continue; + } } - return bitmap; } diff --git a/Excavator/Excavator/CollectionGenericObjects/Garage.cs b/Excavator/Excavator/CollectionGenericObjects/Garage.cs index e3f6f2f..f1c84a5 100644 --- a/Excavator/Excavator/CollectionGenericObjects/Garage.cs +++ b/Excavator/Excavator/CollectionGenericObjects/Garage.cs @@ -1,4 +1,5 @@ using Excavator.Drawnings; +using Excavator.Exceptions; namespace Excavator.CollectionGenericObjects; @@ -36,16 +37,31 @@ public class Garage(int picWidth, int picHeight, ICollectionGenericObjects<Drawn { int width = _pictureWidth / _placeSizeWidth; int height = _pictureHeight / _placeSizeHeight; - for (int i = 0; i < _collection.Count; i++) + + int curWidth = width - 1; + int curHeight = 0; + + for (int i = 0; i < (_collection?.Count ?? 0); i++) { - DrawningTrackedVehicle? excavator = _collection.Get(i); - if (excavator == null) - continue; - int r = i / width; - int s = width - 1 - (i % width); - excavator.SetPictureSize(_pictureWidth, _pictureHeight); - excavator.SetPosition(s * _placeSizeWidth + t, (r * _placeSizeHeight * 2)+ t); - excavator.DrawTransport(g); + try + { + _collection.Get(i).SetPictureSize(_pictureWidth, _pictureHeight); + _collection.Get(i).SetPosition(_placeSizeWidth * curWidth + 10, curHeight * _placeSizeHeight + 10); + } + catch (ObjectNotFoundException) { } + catch (PositionOutOfCollectionException e) { } + if (curWidth > 0) + curWidth--; + else + { + curWidth = width - 1; + curHeight++; + } + + if (curHeight >= height) + { + return; + } } } } diff --git a/Excavator/Excavator/CollectionGenericObjects/ListGenericObjects.cs b/Excavator/Excavator/CollectionGenericObjects/ListGenericObjects.cs index 1c4dadc..dfdfc12 100644 --- a/Excavator/Excavator/CollectionGenericObjects/ListGenericObjects.cs +++ b/Excavator/Excavator/CollectionGenericObjects/ListGenericObjects.cs @@ -1,4 +1,6 @@ - +using Excavator.Exceptions; + + namespace Excavator.CollectionGenericObjects; /// <summary> /// Параметризованный набор объектов @@ -33,31 +35,51 @@ public class ListGenericObjects<T> : ICollectionGenericObjects<T> public T? Get(int position) { - if (position >= Count || position < 0) return null; + if (position < 0 || position >= Count) + { + throw new PositionOutOfCollectionException(position); + } + return _collection[position]; } public int Insert(T obj) { - if (Count + 1 > _maxCount) return -1; + if (Count == _maxCount) + { + throw new CollectionOverflowException(Count); + } + _collection.Add(obj); - return Count; + return _collection.Count; } public int Insert(T obj, int position) { - if (Count + 1 > _maxCount) return -1; - if (position < 0 || position > Count) return -1; - _collection.Insert(position, obj); - return 1; - } + + if (position < 0 || position > Count) + { + throw new PositionOutOfCollectionException(position); + } + if (Count == _maxCount) + { + throw new CollectionOverflowException(Count); + } + _collection.Insert(position, obj); + return position; + } public T? Remove(int position) { - if (position < 0 || position > Count) return null; - T? pos = _collection[position]; + + if (position < 0 || position > Count) + { + throw new PositionOutOfCollectionException(position); + } + + T? obj = _collection[position]; _collection.RemoveAt(position); - return pos; + return obj; } public IEnumerable<T?> GetItems() diff --git a/Excavator/Excavator/CollectionGenericObjects/MassiveGenericObjects.cs b/Excavator/Excavator/CollectionGenericObjects/MassiveGenericObjects.cs index cfb5a8b..ce1751d 100644 --- a/Excavator/Excavator/CollectionGenericObjects/MassiveGenericObjects.cs +++ b/Excavator/Excavator/CollectionGenericObjects/MassiveGenericObjects.cs @@ -1,4 +1,6 @@ +using Excavator.Exceptions; + namespace Excavator.CollectionGenericObjects; /// <summary> @@ -49,53 +51,79 @@ public class MassiveGenericObjects<T> : ICollectionGenericObjects<T> public T? Get(int position) { - if (position < 0 || position > Count) + if (position >= _collection.Length || position < 0) { - return null; + throw new PositionOutOfCollectionException(position); + } + if (_collection[position] == null) + { + throw new ObjectNotFoundException(position); } return _collection[position]; } public int Insert(T excavator) { - return Insert(excavator, 0); - } - public int Insert(T excavator, int position) - { - int nullIndex = -1, i; - if (!(position >= 0 && position < Count)) - return -1; - for (i = position; i < Count; i++) + for (int i = 0; i < Count; i++) { if (_collection[i] == null) { - nullIndex = i; - break; + _collection[i] = excavator; + return i; } } - if (nullIndex < 0) + + throw new CollectionOverflowException(Count); + } + public int Insert(T obj, int position) + { + + if (position < 0 || position >= Count) { - return -1; + throw new PositionOutOfCollectionException(position); } - for (i = nullIndex; i > position; i--) + + if (_collection[position] == null) { - _collection[i] = _collection[i - 1]; + _collection[position] = obj; + return position; } - _collection[position] = excavator; - return position; + + for (int i = position + 1; i < Count; i++) + { + if (_collection[i] == null) + { + _collection[i] = obj; + return i; + } + } + for (int i = position - 1; i >= 0; i--) + { + if (_collection[i] == null) + { + _collection[i] = obj; + return i; + } + } + + throw new CollectionOverflowException(Count); } - public T Remove(int position) + public T? Remove(int position) { - if (position < 0 || position > Count) + + if (position < 0 || position >= Count) { - return null; + throw new PositionOutOfCollectionException(position); + } + if (_collection[position] == null) + { + throw new ObjectNotFoundException(position); } - T drawningTrackedVehicle = _collection[position]; - _collection[position] = null; - - return drawningTrackedVehicle; + T? obj = _collection[position]; + _collection[position] = null; + return obj; } public IEnumerable<T?> GetItems() diff --git a/Excavator/Excavator/CollectionGenericObjects/StorageCollection.cs b/Excavator/Excavator/CollectionGenericObjects/StorageCollection.cs index 62c5d10..02dbf10 100644 --- a/Excavator/Excavator/CollectionGenericObjects/StorageCollection.cs +++ b/Excavator/Excavator/CollectionGenericObjects/StorageCollection.cs @@ -1,5 +1,7 @@ using Excavator.Drawnings; +using Excavator.Exceptions; using System.Text; +using static System.Windows.Forms.LinkLabel; namespace Excavator.CollectionGenericObjects; /// <summary> @@ -88,12 +90,11 @@ public class StorageCollection<T> /// Сохранение информации по автомобилям в хранилище в файл /// </summary> /// <param name="filename">Путь и имя файла</param> - /// <returns>true - сохранение прошло успешно, false - ошибка при сохранении данных</returns> - public bool SaveData(string filename) + public void SaveData(string filename) { if (_storages.Count == 0) { - return false; + throw new NullReferenceException("В хранилище отсутствуют коллекции для сохранения"); } if (File.Exists(filename)) @@ -134,18 +135,16 @@ public class StorageCollection<T> } } - return true; } /// <summary> /// Загрузка информации по автомобилям в хранилище из файла /// </summary> /// <param name="filename">Путь и имя файла</param> - /// <returns>true - загрузка прошла успешно, false - ошибка при загрузке данных</returns> - public bool LoadData(string filename) + public void LoadData(string filename) { if (!File.Exists(filename)) { - return false; + throw new FileNotFoundException("Файл не существует"); } using (StreamReader reader = File.OpenText(filename)) @@ -153,11 +152,11 @@ public class StorageCollection<T> string? str = reader.ReadLine(); if (str == null || str.Length == 0) { - return false; + throw new FileFormatException("В файле нет данных"); } - if (!str.StartsWith(_collectionKey)) + if (!str.Equals(_collectionKey)) { - return false; + throw new FileFormatException("В файле неверные данные"); } _storages.Clear(); string? strs = ""; @@ -175,25 +174,31 @@ public class StorageCollection<T> if (collection == null) { - return false; + throw new InvalidOperationException("Не удалось создать коллекцию"); } collection.MaxCount = Convert.ToInt32(record[2]); string[] set = record[3].Split(_separatorItems, StringSplitOptions.RemoveEmptyEntries); foreach (string elem in set) { - if (elem?.CreateDrawningTrackedVehicle() is T car) + if (elem?.CreateDrawningTrackedVehicle() is T ship) { - if (collection.Insert(car) == -1) + try { - return false; + if (collection.Insert(ship) == -1) + { + throw new InvalidOperationException("Объект не удалось добавить в коллекцию: " + record[3]); + } + } + catch (CollectionOverflowException ex) + { + throw new OverflowException("Коллекция переполнена", ex); } } } _storages.Add(record[0], collection); } - return true; } } /// <summary> diff --git a/Excavator/Excavator/Excavator.csproj b/Excavator/Excavator/Excavator.csproj index af03d74..8a02074 100644 --- a/Excavator/Excavator/Excavator.csproj +++ b/Excavator/Excavator/Excavator.csproj @@ -8,6 +8,29 @@ <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> + <ItemGroup> + <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1" /> + <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="8.0.0" /> + <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" /> + <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> + <PackageReference Include="NLog" Version="5.3.2" /> + <PackageReference Include="NLog.Extensions.Logging" Version="5.3.11" /> + <PackageReference Include="Serilog" Version="3.1.1" /> + <PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" /> + <PackageReference Include="Serilog.Settings.Configuration" Version="8.0.0" /> + <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> + <PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" /> + <PackageReference Include="Walter.Web.FireWall.SqlLogger" Version="2023.11.13.1117" /> + </ItemGroup> + <ItemGroup> <Compile Update="Properties\Resources.Designer.cs"> <DesignTime>True</DesignTime> @@ -23,4 +46,10 @@ </EmbeddedResource> </ItemGroup> + <ItemGroup> + <None Update="serilogConfig.json"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + </ItemGroup> + </Project> \ No newline at end of file diff --git a/Excavator/Excavator/Exceptions/CollectionOverflowException.cs b/Excavator/Excavator/Exceptions/CollectionOverflowException.cs new file mode 100644 index 0000000..4d4cca8 --- /dev/null +++ b/Excavator/Excavator/Exceptions/CollectionOverflowException.cs @@ -0,0 +1,20 @@ +using System.Runtime.Serialization; + +namespace Excavator.Exceptions; + +/// <summary> +/// Класс, описывающий ошибку переполнения коллекции +/// </summary> +[Serializable] +internal class CollectionOverflowException : ApplicationException +{ + public CollectionOverflowException(int count) : base("В коллекции превышено допустимое количество: " + count) { } + + public CollectionOverflowException() : base() { } + + public CollectionOverflowException(string message) : base(message) { } + + public CollectionOverflowException(string message, Exception exception) : base(message, exception) { } + + protected CollectionOverflowException(SerializationInfo info, StreamingContext contex) : base(info, contex) { } +} \ No newline at end of file diff --git a/Excavator/Excavator/Exceptions/ObjectNotFoundException.cs b/Excavator/Excavator/Exceptions/ObjectNotFoundException.cs new file mode 100644 index 0000000..39cf0d7 --- /dev/null +++ b/Excavator/Excavator/Exceptions/ObjectNotFoundException.cs @@ -0,0 +1,20 @@ +using System.Runtime.Serialization; + +namespace Excavator.Exceptions; + +/// <summary> +/// Класс, описывающий ошибку, что по указанной позиции нет элемента +/// </summary> +[Serializable] +internal class ObjectNotFoundException : ApplicationException +{ + public ObjectNotFoundException(int i) : base("Не найден объект по позиции " + i) { } + + public ObjectNotFoundException() : base() { } + + public ObjectNotFoundException(string message) : base(message) { } + + public ObjectNotFoundException(string message, Exception exception) : base(message, exception) { } + + protected ObjectNotFoundException(SerializationInfo info, StreamingContext contex) : base(info, contex) { } +} \ No newline at end of file diff --git a/Excavator/Excavator/Exceptions/PositionOutOfCollectionException.cs b/Excavator/Excavator/Exceptions/PositionOutOfCollectionException.cs new file mode 100644 index 0000000..0fb60d0 --- /dev/null +++ b/Excavator/Excavator/Exceptions/PositionOutOfCollectionException.cs @@ -0,0 +1,15 @@ +using System.Runtime.Serialization; +namespace Excavator.Exceptions; + +/// <summary> +/// Класс, описывающий ошибку выхода за границы коллекции +/// </summary> +[Serializable] +internal class PositionOutOfCollectionException : ApplicationException +{ + public PositionOutOfCollectionException(int i) : base("Выход за границы коллекции.Позиция " + i) { } + public PositionOutOfCollectionException() : base() { } + public PositionOutOfCollectionException(string message) : base(message) { } + public PositionOutOfCollectionException(string message, Exception exception) : base(message, exception) { } + protected PositionOutOfCollectionException(SerializationInfo info, StreamingContext contex) : base(info, contex) { } +} \ No newline at end of file diff --git a/Excavator/Excavator/FormTrackedVehicleCollection.cs b/Excavator/Excavator/FormTrackedVehicleCollection.cs index 2edc8ec..d91cace 100644 --- a/Excavator/Excavator/FormTrackedVehicleCollection.cs +++ b/Excavator/Excavator/FormTrackedVehicleCollection.cs @@ -1,5 +1,7 @@ using Excavator.CollectionGenericObjects; using Excavator.Drawnings; +using Excavator.Exceptions; +using Microsoft.Extensions.Logging; namespace Excavator; @@ -17,13 +19,19 @@ public partial class FormTrackedVehicleCollection : Form /// </summary> private AbstractCompany? _company = null; + /// <summary> + /// Логер + /// </summary> + private readonly ILogger _logger; + /// <summary> /// Конструктор /// </summary> - public FormTrackedVehicleCollection() + public FormTrackedVehicleCollection(ILogger<FormTrackedVehicleCollection> logger) { InitializeComponent(); _storageCollection = new(); + _logger = logger; } @@ -45,7 +53,6 @@ public partial class FormTrackedVehicleCollection : Form private void ButtonAddCar_Click(object sender, EventArgs e) { FormTrackedVehicleConfig form = new(); - form.Show(); form.AddEvent(SetCar); } @@ -56,19 +63,24 @@ public partial class FormTrackedVehicleCollection : Form /// <param name="car"></param> private void SetCar(DrawningTrackedVehicle? car) { - if (_company == null || car == null) + try { - return; - } + if (_company == null || car == null) + { + return; + } - if (_company + car != -1) - { - MessageBox.Show("Объект добавлен"); - pictureBox.Image = _company.Show(); + if (_company + car != -1) + { + MessageBox.Show("Объект добавлен"); + _logger.LogInformation($"Добавлен объект {car.GetDataForSave()}"); + pictureBox.Image = _company.Show(); + } } - else + catch (CollectionOverflowException ex) { - MessageBox.Show("Не удалось добавить объект"); + MessageBox.Show(ex.Message); + _logger.LogWarning($"Ошибка: {ex.Message}"); } } @@ -89,15 +101,25 @@ public partial class FormTrackedVehicleCollection : Form return; } - int pos = Convert.ToInt32(maskedTextBox.Text); - if (_company - pos != null) + try { - MessageBox.Show("Объект удален"); - pictureBox.Image = _company.Show(); + int pos = Convert.ToInt32(maskedTextBox.Text); + if (_company - pos != null) + { + MessageBox.Show("Объект удален"); + _logger.LogInformation($"Удален объект по позиции {pos}"); + pictureBox.Image = _company.Show(); + } } - else + catch (ObjectNotFoundException ex) { - MessageBox.Show("Не удалось удалить объект"); + MessageBox.Show(ex.Message); + _logger.LogError($"Ошибка: {ex.Message}"); + } + catch (PositionOutOfCollectionException ex) + { + MessageBox.Show(ex.Message); + _logger.LogError($"Ошибка: {ex.Message}"); } } @@ -253,18 +275,18 @@ public partial class FormTrackedVehicleCollection : Form { if (saveFileDialog.ShowDialog() == DialogResult.OK) { - if (_storageCollection.SaveData(saveFileDialog.FileName)) + try { - MessageBox.Show("Сохранение прошло успешно", - "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); + _storageCollection.SaveData(saveFileDialog.FileName); + MessageBox.Show("Сохранение прошло успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); + _logger.LogInformation("Сохранение в файл: {filename}", saveFileDialog.FileName); } - else + catch (Exception ex) { - MessageBox.Show("Не сохранилось", "Результат", - MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show(ex.Message, "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogError("Ошибка: {Message}", ex.Message); } } - } /// <summary> /// Обработка нажатия "Загрузка" @@ -275,16 +297,17 @@ public partial class FormTrackedVehicleCollection : Form { if (openFileDialog.ShowDialog() == DialogResult.OK) { - if (_storageCollection.LoadData(openFileDialog.FileName)) + try { - MessageBox.Show("Загрузка прошла успешно", - "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); + _storageCollection.LoadData(openFileDialog.FileName); + MessageBox.Show("Загрузка прошло успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); RerfreshListBoxItems(); + _logger.LogInformation("Загрузка из фала: {filename}", openFileDialog.FileName); } - else + catch (Exception ex) { - MessageBox.Show("Не загрузилось", "Результат", - MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show("Не загрузилось", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogError("Ошибка: {Message}", ex.Message); } } } diff --git a/Excavator/Excavator/Program.cs b/Excavator/Excavator/Program.cs index f33af9d..fb1b1c4 100644 --- a/Excavator/Excavator/Program.cs +++ b/Excavator/Excavator/Program.cs @@ -1,3 +1,8 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; +using Serilog; + namespace Excavator { internal static class Program @@ -8,10 +13,28 @@ namespace Excavator [STAThread] static void Main() { - // To customize application configuration such as set high DPI settings or default font, - // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new FormTrackedVehicleCollection()); + + ServiceCollection services = new(); + ConfigureServices(services); + using ServiceProvider serviceProvider = services.BuildServiceProvider(); + Application.Run(serviceProvider.GetRequiredService<FormTrackedVehicleCollection>()); + } + + private static void ConfigureServices(ServiceCollection services) + { + services + .AddSingleton<FormTrackedVehicleCollection>() + .AddLogging(option => + { + option.SetMinimumLevel(LogLevel.Information); + var config = new ConfigurationBuilder() + .AddJsonFile("serilogConfig.json", optional: false, reloadOnChange: true) + .Build(); + option.AddSerilog(Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) + .CreateLogger()); + }); } } } \ No newline at end of file diff --git a/Excavator/Excavator/serilogConfig.json b/Excavator/Excavator/serilogConfig.json new file mode 100644 index 0000000..50717a4 --- /dev/null +++ b/Excavator/Excavator/serilogConfig.json @@ -0,0 +1,20 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.File" ], + "MinimumLevel": "Information", + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Logs/log_.log", + "rollingInterval": "Day", + "outputTemplate": "[{Timestamp:HH:mm:ss.fff}]{Level:u4}: {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], + "Properties": { + "Application": "Excavator" + } + } +} \ No newline at end of file