diff --git a/ProjectLocomotive/ProjectLocomotive/EntityElectricLocomotive.cs b/ProjectLocomotive/ProjectLocomotive/EntityElectricLocomotive.cs index 9edc44c..dc125de 100644 --- a/ProjectLocomotive/ProjectLocomotive/EntityElectricLocomotive.cs +++ b/ProjectLocomotive/ProjectLocomotive/EntityElectricLocomotive.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace ProjectLocomotive { - internal class EntityElectricLocomotive : EntityLocomotive + public class EntityElectricLocomotive : EntityLocomotive { /// /// Дополнительный цвет diff --git a/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.Designer.cs b/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.Designer.cs index 78944f7..0d17b61 100644 --- a/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.Designer.cs +++ b/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.Designer.cs @@ -69,11 +69,11 @@ this.groupBoxTools.Controls.Add(this.maskedTextBoxPosition); this.groupBoxTools.Controls.Add(this.buttonAddLocomotive); this.groupBoxTools.Dock = System.Windows.Forms.DockStyle.Right; - this.groupBoxTools.Location = new System.Drawing.Point(580, 33); + this.groupBoxTools.Location = new System.Drawing.Point(577, 33); this.groupBoxTools.Margin = new System.Windows.Forms.Padding(4); this.groupBoxTools.Name = "groupBoxTools"; this.groupBoxTools.Padding = new System.Windows.Forms.Padding(4); - this.groupBoxTools.Size = new System.Drawing.Size(220, 535); + this.groupBoxTools.Size = new System.Drawing.Size(220, 510); this.groupBoxTools.TabIndex = 0; this.groupBoxTools.TabStop = false; this.groupBoxTools.Text = "Инструменты"; @@ -248,7 +248,7 @@ this.pictureBox.Location = new System.Drawing.Point(0, 33); this.pictureBox.Margin = new System.Windows.Forms.Padding(4); this.pictureBox.Name = "pictureBox"; - this.pictureBox.Size = new System.Drawing.Size(580, 535); + this.pictureBox.Size = new System.Drawing.Size(577, 510); this.pictureBox.TabIndex = 1; this.pictureBox.TabStop = false; // @@ -259,7 +259,7 @@ this.fileToolStripMenuItem}); this.menuStrip.Location = new System.Drawing.Point(0, 0); this.menuStrip.Name = "menuStrip"; - this.menuStrip.Size = new System.Drawing.Size(800, 33); + this.menuStrip.Size = new System.Drawing.Size(797, 33); this.menuStrip.TabIndex = 2; // // fileToolStripMenuItem @@ -297,7 +297,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 568); + this.ClientSize = new System.Drawing.Size(797, 543); this.Controls.Add(this.pictureBox); this.Controls.Add(this.groupBoxTools); this.Controls.Add(this.menuStrip); diff --git a/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.cs b/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.cs index 0cbe158..1ad7f37 100644 --- a/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.cs +++ b/ProjectLocomotive/ProjectLocomotive/FormMapWithSetLocomotives.cs @@ -1,4 +1,5 @@ using Locomotive; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.ComponentModel; @@ -23,10 +24,14 @@ namespace ProjectLocomotive }; /// Объект от коллекции карт private readonly MapsCollection _mapsCollection; - public FormMapWithSetLocomotives() + /// Логер + /// + private readonly ILogger _logger; + public FormMapWithSetLocomotives(ILogger logger) { InitializeComponent(); _mapsCollection = new MapsCollection(pictureBox.Width, pictureBox.Height); + _logger = logger; comboBoxSelectorMap.Items.Clear(); foreach (var elem in _mapsDict) { @@ -63,16 +68,27 @@ namespace ProjectLocomotive { if (listBoxMaps.SelectedIndex == -1) { - return; + MessageBox.Show("Перед добавлением объекта необходимо создать карту"); } - if (_mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty] + new DrawningObject(locomotive) != -1) + try { + if (_mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty] + new DrawningObject(locomotive) != -1) + { MessageBox.Show("Объект добавлен"); + _logger.LogInformation("Добавлен объект {@locomotive}", locomotive); pictureBox.Image = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].ShowSet(); + } + else + { + MessageBox.Show("Не удалось добавить объект"); + _logger.LogInformation("Не удалось добавить объект {@locomotive}", locomotive); + } } - else + catch(StorageOverflowException ex) { - MessageBox.Show("Ошибка при добавлении объекта"); + MessageBox.Show("Не удалось добавить объект"); + _logger.LogWarning("Ошибка переполнения хранилища: {0}", ex.Message); + MessageBox.Show($"Ошибка переполнения хранилища: {ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// Удаление объекта @@ -91,14 +107,25 @@ namespace ProjectLocomotive return; } int pos = Convert.ToInt32(maskedTextBoxPosition.Text); - if (_mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty] - pos != null) + try { - MessageBox.Show("Объект удален"); - pictureBox.Image = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].ShowSet(); + var deletedLocomotive = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty] - pos; + if (deletedLocomotive != null) + { + MessageBox.Show("Объект удалён"); + _logger.LogInformation("Из текущей карты удалён объект {@locomotive}", deletedLocomotive); + pictureBox.Image = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].ShowSet(); + } + else + { + _logger.LogInformation("Не удалось добавить объект по позиции {0} равен null", pos); + MessageBox.Show("Не удалось удалить объект"); + } } - else + catch (LocomotiveNotFoundException ex) { - MessageBox.Show("Не удалось удалить объект"); + _logger.LogWarning("Ошибка удаления: {0}", ex.Message); + MessageBox.Show($"Ошибка удаления: {ex.Message}"); } } /// Вывод набора @@ -158,6 +185,7 @@ namespace ProjectLocomotive if (MessageBox.Show($"Удалить карту {listBoxMaps.SelectedItem}?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { _mapsCollection.DelMap(listBoxMaps.SelectedItem?.ToString() ?? string.Empty); + _logger.LogInformation("Удалена карта {0}", listBoxMaps.SelectedItem?.ToString() ?? string.Empty); ReloadMaps(); } } @@ -165,6 +193,7 @@ namespace ProjectLocomotive private void listBoxMaps_SelectedIndexChanged(object sender, EventArgs e) { pictureBox.Image = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].ShowSet(); + _logger.LogInformation("Был осуществлен переход на карту под названием: {0}", listBoxMaps.SelectedItem?.ToString() ?? string.Empty); } /// Добавление карты private void buttonAddMap_Click(object sender, EventArgs e) @@ -172,27 +201,33 @@ namespace ProjectLocomotive if (comboBoxSelectorMap.SelectedIndex == -1 || string.IsNullOrEmpty(textBoxNewMapName.Text)) { MessageBox.Show("Не все данные заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogInformation("При добавлении карты {0}", comboBoxSelectorMap.SelectedIndex == -1 ? "Не была выбрана карта" : "Не была названа карта"); return; } if (!_mapsDict.ContainsKey(comboBoxSelectorMap.Text)) { MessageBox.Show("Нет такой карты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogWarning("Нет карты с названием: {0}", textBoxNewMapName.Text); return; } _mapsCollection.AddMap(textBoxNewMapName.Text, _mapsDict[comboBoxSelectorMap.Text]); ReloadMaps(); + _logger.LogInformation("Добавлена карта {0}", textBoxNewMapName.Text); } private void saveToolStripMenuItem_Click(object sender, EventArgs e) { if (saveFileDialog.ShowDialog() == DialogResult.OK) { - if (_mapsCollection.SaveData(saveFileDialog.FileName)) + try { - MessageBox.Show("Saved successfully", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); + _mapsCollection.SaveData(saveFileDialog.FileName); + _logger.LogInformation("Сохранение прошло успешно. Файл находится: {0}", saveFileDialog.FileName); + MessageBox.Show("Сохранение прошло успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information); } - else + catch (Exception ex) { - MessageBox.Show("Saving failed", "Result", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show($"Не сохранилось: {ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogWarning("Не удалось сохранить файл '{0}'. Текст ошибки: {1}", saveFileDialog.FileName, ex.Message); } } } @@ -200,16 +235,18 @@ namespace ProjectLocomotive { if (loadFileDialog.ShowDialog() == DialogResult.OK) { - if (_mapsCollection.LoadData(loadFileDialog.FileName)) + try { - MessageBox.Show("Loaded successfully", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); + _mapsCollection.LoadData(loadFileDialog.FileName); + MessageBox.Show("Открытие прошло успешно", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); + _logger.LogInformation("Открытие файла '{0}' прошло успешно", loadFileDialog.FileName); + ReloadMaps(); } - else - { - MessageBox.Show("Loading failed", "Result", MessageBoxButtons.OK, MessageBoxIcon.Error); + catch (Exception ex) + { + MessageBox.Show($"Не удалось открыть: {ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogWarning("Не удалось открыть файл {0}. Текст ошибки: {1}", loadFileDialog.FileName, ex.Message); } - ReloadMaps(); - pictureBox.Image = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].ShowSet(); } } } diff --git a/ProjectLocomotive/ProjectLocomotive/LocomotiveNotFoundException.cs b/ProjectLocomotive/ProjectLocomotive/LocomotiveNotFoundException.cs new file mode 100644 index 0000000..b2a1a7c --- /dev/null +++ b/ProjectLocomotive/ProjectLocomotive/LocomotiveNotFoundException.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectLocomotive +{ + internal class LocomotiveNotFoundException : ApplicationException + { + public LocomotiveNotFoundException(int i) : base($"Не найден объект по позиции {i}") { } + public LocomotiveNotFoundException() : base() { } + public LocomotiveNotFoundException(string message) : base(message) { } + public LocomotiveNotFoundException(string message, Exception exception) : + base(message, exception) + { } + protected LocomotiveNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } + } +} diff --git a/ProjectLocomotive/ProjectLocomotive/MapsCollection.cs b/ProjectLocomotive/ProjectLocomotive/MapsCollection.cs index c11a9eb..98ce101 100644 --- a/ProjectLocomotive/ProjectLocomotive/MapsCollection.cs +++ b/ProjectLocomotive/ProjectLocomotive/MapsCollection.cs @@ -52,7 +52,7 @@ namespace Locomotive } } /// Сохранение информации по локомотивам в хранилище в файл - public bool SaveData(string filename) + public void SaveData(string filename) { if (File.Exists(filename)) { @@ -69,14 +69,13 @@ namespace Locomotive ); } } - return true; } /// Загрузка информации по локомотивам в депо из файла - public bool LoadData(string filename) + public void LoadData(string filename) { if (!File.Exists(filename)) { - return false; + throw new FileNotFoundException("Файл не найден"); } using (FileStream fs = new(filename, FileMode.Open)) using (StreamReader sr = new StreamReader(fs, Encoding.UTF8)) @@ -85,7 +84,7 @@ namespace Locomotive if (!curLine.Contains("MapsCollection")) { - return false; + throw new FileFormatException("Формат данных в файле неправильный"); } _mapStorages.Clear(); while ((curLine = sr.ReadLine()) != null) @@ -105,11 +104,9 @@ namespace Locomotive map = new RailroadMap(); break; } - _mapStorages.Add(elems[0], new MapWithSetLocomotivesGeneric(_pictureWidth, _pictureHeight, map)); _mapStorages[elems[0]].LoadData(elems[2].Split(separatorData, StringSplitOptions.RemoveEmptyEntries)); } - return true; } } } diff --git a/ProjectLocomotive/ProjectLocomotive/Program.cs b/ProjectLocomotive/ProjectLocomotive/Program.cs index e256676..86ef8be 100644 --- a/ProjectLocomotive/ProjectLocomotive/Program.cs +++ b/ProjectLocomotive/ProjectLocomotive/Program.cs @@ -1,3 +1,9 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NLog.Extensions.Logging; +using Serilog; + namespace ProjectLocomotive { internal static class Program @@ -11,7 +17,28 @@ namespace ProjectLocomotive // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new FormMapWithSetLocomotives()); + var services = new ServiceCollection(); + ConfigureServices(services); + using (ServiceProvider serviceProvider = services.BuildServiceProvider()) + { + Application.Run(serviceProvider.GetRequiredService()); + } + } + private static void ConfigureServices(ServiceCollection services) + { + services.AddSingleton() + .AddLogging(option => + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true) + .Build(); + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .CreateLogger(); + option.SetMinimumLevel(LogLevel.Information); + option.AddSerilog(logger); + }); } } } \ No newline at end of file diff --git a/ProjectLocomotive/ProjectLocomotive/ProjectLocomotive.csproj b/ProjectLocomotive/ProjectLocomotive/ProjectLocomotive.csproj index 13ee123..8b93a81 100644 --- a/ProjectLocomotive/ProjectLocomotive/ProjectLocomotive.csproj +++ b/ProjectLocomotive/ProjectLocomotive/ProjectLocomotive.csproj @@ -8,6 +8,30 @@ enable + + + + + + + Always + + + + + + + + + + + + + + + + + True @@ -23,4 +47,10 @@ + + + Always + + + \ No newline at end of file diff --git a/ProjectLocomotive/ProjectLocomotive/SetLocomotivesGeneric.cs b/ProjectLocomotive/ProjectLocomotive/SetLocomotivesGeneric.cs index dda3033..6b0e991 100644 --- a/ProjectLocomotive/ProjectLocomotive/SetLocomotivesGeneric.cs +++ b/ProjectLocomotive/ProjectLocomotive/SetLocomotivesGeneric.cs @@ -15,14 +15,13 @@ namespace ProjectLocomotive { /// Список хранимых объектов private readonly List _places; - /// Количество объектов в списке public int Count => _places.Count; - private readonly int _maxCount; + private readonly int _maxCount = 15; /// Конструктор public SetLocomotivesGeneric(int count) { - _maxCount = count; + _maxCount = count = 15; _places = new List(); } /// Добавление объекта в набор @@ -33,16 +32,17 @@ namespace ProjectLocomotive /// Добавление объекта в набор на конкретную позицию public int Insert(T locomotive, int position) { - if (position >= _maxCount || position < 0) return -1; + if (position < 0) return -1; + if (Count >= _maxCount) throw new StorageOverflowException(_maxCount); _places.Insert(position, locomotive); return position; } /// Удаление объекта из набора с конкретной позиции public T Remove(int position) { - if (position >= _maxCount || position < 0) return null; + if (_places[position] is null) throw new LocomotiveNotFoundException(position); T result = _places[position]; - _places.RemoveAt(position); + _places[position] = null; return result; } // Индексатор @@ -68,10 +68,6 @@ namespace ProjectLocomotive { yield return locomotive; } - else - { - yield break; - } } } } diff --git a/ProjectLocomotive/ProjectLocomotive/StorageOverflowException.cs b/ProjectLocomotive/ProjectLocomotive/StorageOverflowException.cs new file mode 100644 index 0000000..aa07280 --- /dev/null +++ b/ProjectLocomotive/ProjectLocomotive/StorageOverflowException.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectLocomotive +{ + internal class StorageOverflowException : ApplicationException + { + public StorageOverflowException(int count) : base($"В наборе превышено допустимое количество: {count}") { } + public StorageOverflowException() : base() { } + public StorageOverflowException(string message) : base(message) { } + public StorageOverflowException(string message, Exception exception) : + base(message, exception) + { } + protected StorageOverflowException(SerializationInfo info, StreamingContext context) : base(info, context) { } + } +} diff --git a/ProjectLocomotive/ProjectLocomotive/appsettings.json b/ProjectLocomotive/ProjectLocomotive/appsettings.json new file mode 100644 index 0000000..c850b36 --- /dev/null +++ b/ProjectLocomotive/ProjectLocomotive/appsettings.json @@ -0,0 +1,48 @@ +{ + "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" ], + "Destructure": [ + { + "Name": "ByTransforming", + "Args": { + "returnType": "ProjectLocomotive.EntityLocomotive", + "transformation": "r => new { BodyColor = r.BodyColor.Name, r.Speed, r.Weight }" + } + }, + { + "Name": "ByTransforming", + "Args": { + "returnType": "ProjectLocomotive.EntityElectricLocomotive", + "transformation": "r => new { BodyColor = r.BodyColor.Name, DopColor = r.DopColor.Name, r.ElectroLines, r.ElectroBattery, r.Speed, r.Weight }" + } + }, + { + "Name": "ToMaximumDepth", + "Args": { "maximumDestructuringDepth": 4 } + }, + { + "Name": "ToMaximumStringLength", + "Args": { "maximumStringLength": 100 } + }, + { + "Name": "ToMaximumCollectionCount", + "Args": { "maximumCollectionCount": 15 } + } + ], + "Properties": { + "Application": "ProjectLocomotive" + } + } +} \ No newline at end of file diff --git a/ProjectLocomotive/ProjectLocomotive/nlog.config b/ProjectLocomotive/ProjectLocomotive/nlog.config new file mode 100644 index 0000000..905dbb7 --- /dev/null +++ b/ProjectLocomotive/ProjectLocomotive/nlog.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file