diff --git a/BlacksmithWorkshop/BlacksmithWorkshop.sln b/BlacksmithWorkshop/BlacksmithWorkshop.sln
index feccacf..6609d26 100644
--- a/BlacksmithWorkshop/BlacksmithWorkshop.sln
+++ b/BlacksmithWorkshop/BlacksmithWorkshop.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlacksmithWorkshopDataModel
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlacksmithWorkshopContracts", "BlacksmithWorkshopContracts\BlacksmithWorkshopContracts.csproj", "{EBDA1A18-346F-4427-BC86-ED41C062A75B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlacksmithWorkshopBusinessLogic", "BlacksmithWorkshopBusinessLogic\BlacksmithWorkshopBusinessLogic.csproj", "{B3C97222-2894-4D74-B0D7-B3BEB347081D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
{EBDA1A18-346F-4427-BC86-ED41C062A75B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBDA1A18-346F-4427-BC86-ED41C062A75B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EBDA1A18-346F-4427-BC86-ED41C062A75B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B3C97222-2894-4D74-B0D7-B3BEB347081D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B3C97222-2894-4D74-B0D7-B3BEB347081D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B3C97222-2894-4D74-B0D7-B3BEB347081D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B3C97222-2894-4D74-B0D7-B3BEB347081D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BlacksmithWorkshopBusinessLogic.csproj b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BlacksmithWorkshopBusinessLogic.csproj
new file mode 100644
index 0000000..132c02c
--- /dev/null
+++ b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BlacksmithWorkshopBusinessLogic.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogic/ComponentLogic.cs b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogic/ComponentLogic.cs
new file mode 100644
index 0000000..4887f09
--- /dev/null
+++ b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogic/ComponentLogic.cs
@@ -0,0 +1,152 @@
+using BlacksmithWorkshopContracts.BindingModels;
+using BlacksmithWorkshopContracts.BusinessLogicsContracts;
+using BlacksmithWorkshopContracts.SearchModels;
+using BlacksmithWorkshopContracts.StoragesContracts;
+using BlacksmithWorkshopContracts.ViewModels;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BlacksmithWorkshopBusinessLogic.BusinessLogic
+{
+ //класс, реализующий логику для компонентов
+ public class ComponentLogic : IComponentLogic
+ {
+ private readonly ILogger _logger;
+
+ private readonly IComponentStorage _componentStorage;
+
+ //конструктор
+ public ComponentLogic(ILogger logger, IComponentStorage componentStorage)
+ {
+ _logger = logger;
+ _componentStorage = componentStorage;
+ }
+
+ //вывод отфильтрованного списка компонентов
+ public List? ReadList(ComponentSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. ComponentName:{ComponentName}. Id:{Id}", model?.ComponentName, model?.Id);
+
+ //list хранит весь список в случае, если model пришло со значением null на вход метода
+ var list = model == null ? _componentStorage.GetFullList() : _componentStorage.GetFilteredList(model);
+
+ if(list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+
+ _logger.LogInformation("ReadList. Count:{Count}", list.Count);
+
+ return list;
+ }
+
+ //вывод конкретного компонента
+ public ComponentViewModel? ReadElement(ComponentSearchModel model)
+ {
+ if(model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+
+ _logger.LogInformation("ReadElement. ComponentName:{Componentame}. Id:{Id}", model.ComponentName, model.Id);
+
+ var element = _componentStorage.GetElement(model);
+
+ if(element == null)
+ {
+ _logger.LogWarning("ReadElement element not found");
+ return null;
+ }
+
+ _logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
+
+ return element;
+ }
+
+ //создание компонента
+ public bool Create(ComponentBindingModel model)
+ {
+ CheckModel(model);
+
+ if(_componentStorage.Insert(model) == null)
+ {
+ _logger.LogWarning("Insert operation failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ //обновление компонента
+ public bool Update(ComponentBindingModel model)
+ {
+ CheckModel(model);
+
+ if(_componentStorage.Update(model) == null)
+ {
+ _logger.LogWarning("Update operation failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ //удаление компонента
+ public bool Delete(ComponentBindingModel model)
+ {
+ CheckModel(model);
+
+ if (_componentStorage.Delete(model) == null)
+ {
+ _logger.LogWarning("Delete operation failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ //проверка входного аргумента для методов Insert, Update и Delete
+ private void CheckModel(ComponentBindingModel model, bool withParams = true)
+ {
+ if(model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+
+ //если без параметров?
+ if (!withParams)
+ {
+ return;
+ }
+
+ //проверка на наличие названия компонента
+ if (string.IsNullOrEmpty(model.ComponentName){
+ throw new ArgumentNullException("Нет названия компонента", nameof(model.ComponentName));
+ }
+
+ //проверка на наличие нормальной цены у компонента
+ if(model.Cost <= 0)
+ {
+ throw new ArgumentNullException("Цен компонента должна быть больше 0", nameof(model.Cost));
+ }
+
+ _logger.LogInformation("Component. ComponentName:{ComponentName}. Cost:{Cost}. Id:{Id}", model.ComponentName, model.Cost, model.Id);
+
+ //проверка на наличие такого же компонента в списке
+ var element = _componentStorage.GetElement(new ComponentSearchModel
+ {
+ ComponentName = model.ComponentName,
+ });
+
+ if(element != null && element.Id != model.Id)
+ {
+ throw new InvalidOperationException("Компонент с таким названием уже есть");
+ }
+ }
+ }
+}