Stage 3: BussinessLogic(Подправил Card и операции), RestAPI (Добавил контроллеры и немного в Program logs)

This commit is contained in:
nikbel2004@outlook.com 2024-04-30 16:37:32 +04:00
parent 242c2a7d14
commit db7fa7300b
25 changed files with 1105 additions and 164 deletions

View File

@ -3,15 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34202.233
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankView", "Bank\BankView.csproj", "{C867FBC3-FA1E-479D-8368-D6EFAA70CA4B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BankView", "Bank\BankView.csproj", "{C867FBC3-FA1E-479D-8368-D6EFAA70CA4B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankBusinessLogic", "BankBusinessLogic\BankBusinessLogic.csproj", "{FB305193-03D5-40E1-84E9-A27A81D7DB83}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BankBusinessLogic", "BankBusinessLogic\BankBusinessLogic.csproj", "{FB305193-03D5-40E1-84E9-A27A81D7DB83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankDataModels", "BankDataModels\BankDataModels.csproj", "{A2791B88-CAB3-4D95-81E2-6724C9B6CB41}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BankDataModels", "BankDataModels\BankDataModels.csproj", "{A2791B88-CAB3-4D95-81E2-6724C9B6CB41}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankContracts", "BankContracts\BankContracts.csproj", "{060D1745-51EC-49A1-8FC0-B78E64DAE760}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BankContracts", "BankContracts\BankContracts.csproj", "{060D1745-51EC-49A1-8FC0-B78E64DAE760}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankDatabaseImplement", "BankDatabaseImplement\BankDatabaseImplement.csproj", "{F485D64A-2C3A-419A-AB74-80DEC552BFEC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BankDatabaseImplement", "BankDatabaseImplement\BankDatabaseImplement.csproj", "{F485D64A-2C3A-419A-AB74-80DEC552BFEC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankRestAPI", "BankRestAPI\BankRestAPI.csproj", "{A0F0B305-2E9E-4472-9A4F-56DD1F5088E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -39,6 +41,10 @@ Global
{F485D64A-2C3A-419A-AB74-80DEC552BFEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F485D64A-2C3A-419A-AB74-80DEC552BFEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F485D64A-2C3A-419A-AB74-80DEC552BFEC}.Release|Any CPU.Build.0 = Release|Any CPU
{A0F0B305-2E9E-4472-9A4F-56DD1F5088E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A0F0B305-2E9E-4472-9A4F-56DD1F5088E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A0F0B305-2E9E-4472-9A4F-56DD1F5088E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0F0B305-2E9E-4472-9A4F-56DD1F5088E6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -7,7 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>
<ItemGroup>

View File

@ -17,9 +17,12 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
private readonly ILogger _logger;
private readonly IAccountStorage _accountStorage;
private readonly ICashWithdrawalLogic _cashWithdrawalLogic;
private readonly IMoneyTransferLogic _moneyTransferLogic;
// Конструктор
public AccountLogic(ILogger<AccountLogic> logger, IAccountStorage accountStorage,
ICashWithdrawalLogic cashWithdrawalLogic, IMoneyTransferLogic moneyTransferLogic)
{
@ -29,6 +32,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
_moneyTransferLogic = moneyTransferLogic;
}
// Вывод конкретного счёта
public AccountViewModel? ReadElement(AccountSearchModel model)
{
if (model == null)
@ -52,9 +56,10 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return element;
}
// Вывод всего списка счетов
public List<AccountViewModel>? ReadList(AccountSearchModel? model)
{
//_logger.LogInformation("ReadList. AccountNumber:{AccountNumber}. Id:{Id}", model.AccountNumber, model?.Id);
_logger.LogInformation("ReadList. AccountNumber:{AccountNumber}. Id:{Id}", model.AccountNumber, model?.Id);
//list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _accountStorage.GetFullList() : _accountStorage.GetFilteredList(model);
@ -70,10 +75,10 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return list;
}
//метод, отвечающий за изменение баланса счёта
// Метод, отвечающий за изменение баланса счёта
public bool ChangeBalance(AccountSearchModel? model, int sum)
{
//ищем счёт
// Ищем счёт
var account = ReadElement(model);
if (account == null)
@ -81,13 +86,13 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
throw new ArgumentNullException("Счёт не найден", nameof(account));
}
//проверяем возможность операции снятия (sum может быть отрицательной)
// Проверяем возможность операции снятия (sum может быть отрицательной)
if (sum + account.Balance < 0)
{
return false;
}
//обновляем балланс счёта
// Обновляем балланс счёта
_accountStorage.Update(new AccountBindingModel
{
Id = account.Id,
@ -97,6 +102,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
// Создание счёта
public bool Create(AccountBindingModel model)
{
CheckModel(model);
@ -111,6 +117,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
// Обновление счёта
public bool Update(AccountBindingModel model)
{
CheckModel(model);
@ -125,6 +132,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
// Удаление счёта
public bool Delete(AccountBindingModel model)
{
CheckModel(model, false);
@ -141,8 +149,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
//проверка входного аргумента для методов Insert, Update и Delete
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(AccountBindingModel model, bool withParams = true)
{
if (model == null)
@ -150,25 +157,28 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
throw new ArgumentNullException(nameof(model));
}
//так как при удалении передаём как параметр false
// Так как при удалении передаём как параметр false
if (!withParams)
{
return;
}
//проверка на наличие номера счёта
// Проверка на наличие номера счёта
if (string.IsNullOrEmpty(model.AccountNumber))
{
throw new ArgumentNullException("Отсутствие номера у счёта", nameof(model.AccountNumber));
}
//проверка на наличие id владельца
if (model.CashierId < 0)
{
throw new ArgumentNullException("Некорректный Id владельца счёта", nameof(model.CashierId));
}
// Проверка на наличие id владельца
//проверка на наличие id кассира, создавшего счёт
// СОЗВОН ИБО Я НЕ ПОН, А ЗАЧЕМ ЛИШКА ИЛИ МОЖЕТ ЭТО КЛИЕНТ ИМЕЛСЯ ВВИДУ???!
//if (model.CashierId < 0)
//{
// throw new ArgumentNullException("Некорректный Id владельца счёта", nameof(model.CashierId));
//}
// Проверка на наличие id кассира, создавшего счёт
if (model.CashierId < 0)
{
throw new ArgumentNullException("Некорректный Id кассира, открывшего счёт", nameof(model.CashierId));
@ -179,7 +189,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
throw new ArgumentNullException("Изначальный баланс аккаунта не может быть < 0", nameof(model.Balance));
}
//проверка на корректную дату открытия счёта
// Проверка на корректную дату открытия счёта
if (model.DateOpen > DateTime.Now)
{
throw new ArgumentNullException("Дата открытия счёта не может быть ранее текущей", nameof(model.DateOpen));
@ -189,18 +199,17 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
"CashierId:{CashierId}. DateOpen:{DateOpen}. Id:{Id}",
model.AccountNumber, model.ClientId, model.CashierId, model.DateOpen, model.Id);
//для проверка на наличие такого же счёта
// Для проверка на наличие такого же счёта
var element = _accountStorage.GetElement(new AccountSearchModel
{
AccountNumber = model.AccountNumber,
});
//если элемент найден и его Id не совпадает с Id переданного объекта
// Если элемент найден и его Id не совпадает с Id переданного объекта
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Счёт с таким номером уже существует");
}
}
}
}

View File

@ -22,6 +22,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
private readonly IDebitingStorage _debitingStorage;
// Конструктор
public CashWithdrawalLogic(ILogger<CashWithdrawalLogic> logger, ICashWithdrawalStorage cashWithdrawalStorage,
IDebitingStorage debitingStorage)
{
@ -30,6 +31,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
_debitingStorage = debitingStorage;
}
// Вывод конкретной операции
public CashWithdrawalViewModel? ReadElement(CashWithdrawalSearchModel model)
{
if (model == null)
@ -54,12 +56,13 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return element;
}
// Вывод всего списка операций
public List<CashWithdrawalViewModel>? ReadList(CashWithdrawalSearchModel? model)
{
_logger.LogInformation("ReadElement. AccountId:{AccountId}. Sum:{Sum}. DateWithdrawal:{DateWithdrawal}. Id:{Id}",
model?.AccountId, model?.Sum, model?.DateWithdrawal, model?.Id);
//list хранит весь список в случае, если model пришло со значением null на вход метода
// list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _cashWithdrawalStorage.GetFullList() : _cashWithdrawalStorage.GetFilteredList(model);
if (list == null)
@ -73,6 +76,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return list;
}
// Создание операции
public bool Create(CashWithdrawalBindingModel model, bool flag)
{
CheckModel(model);
@ -102,6 +106,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
// Обновление операции
public bool Update(CashWithdrawalBindingModel model)
{
CheckModel(model);
@ -116,6 +121,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
// Удаление операции
public bool Delete(CashWithdrawalBindingModel model)
{
CheckModel(model, false);
@ -132,7 +138,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
//проверка входного аргумента для методов Insert, Update и Delete
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(CashWithdrawalBindingModel model, bool withParams = true)
{
if (model == null)
@ -140,25 +146,25 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
throw new ArgumentNullException(nameof(model));
}
//так как при удалении передаём как параметр false
// Так как при удалении передаём как параметр false
if (!withParams)
{
return;
}
//проверка на корректность Id счёта
// Проверка на корректность Id счёта
if (model.AccountId < 0)
{
throw new ArgumentNullException("Некорректный Id счёта", nameof(model.AccountId));
}
//проверка на корректность снимаемой суммы
// Проверка на корректность снимаемой суммы
if (model.Sum <= 0)
{
throw new ArgumentNullException("Снимаемая сумма не может раняться нулю или быть меньше его", nameof(model.Sum));
}
//проверка на корректную дату операции
// Проверка на корректную дату операции
if (model.DateWithdrawal > DateTime.Now)
{
throw new ArgumentNullException("Дата операции не может быть позднее текущей", nameof(model.DateWithdrawal));

View File

@ -22,6 +22,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
public readonly ICreditingStorage _creditingStorage;
// Конструктор
public MoneyTransferLogic(ILogger<MoneyTransferLogic> logger, IMoneyTransferStorage moneyTransferStorage, ICreditingStorage creditingStorage)
{
_logger = logger;
@ -29,6 +30,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
_creditingStorage = creditingStorage;
}
// Вывод конкретной операции
public MoneyTransferViewModel? ReadElement(MoneyTransferSearchModel model)
{
if (model == null)
@ -53,12 +55,13 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return element;
}
// Вывод всего списка операций
public List<MoneyTransferViewModel>? ReadList(MoneyTransferSearchModel? model)
{
_logger.LogInformation("ReadElement. AccountSenderId:{AccountSenderId}. AccountPayeeId:{AccountPayeeId}. Sum:{Sum}. Id:{Id}",
model?.AccountSenderId, model?.AccountPayeeId, model?.Sum, model?.Id);
//list хранит весь список в случае, если model пришло со значением null на вход метода
// list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _moneyTransferStorage.GetFullList() : _moneyTransferStorage.GetFilteredList(model);
if (list == null)
@ -72,6 +75,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return list;
}
// Создание операции на перевод
public bool Create(MoneyTransferBindingModel model)
{
CheckModel(model);
@ -96,6 +100,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
// Обновление операции на перевод
public bool Update(MoneyTransferBindingModel model)
{
CheckModel(model);
@ -110,6 +115,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
// Удаление операции на перевод
public bool Delete(MoneyTransferBindingModel model)
{
CheckModel(model, false);
@ -126,7 +132,7 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
return true;
}
//проверка входного аргумента для методов Insert, Update и Delete
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(MoneyTransferBindingModel model, bool withParams = true)
{
if (model == null)
@ -134,31 +140,31 @@ namespace BankBusinessLogic.BusinessLogic.Cashier
throw new ArgumentNullException(nameof(model));
}
//так как при удалении передаём как параметр false
// Так как при удалении передаём как параметр false
if (!withParams)
{
return;
}
//проверка корректности Id счёта отправителя
// Проверка корректности Id счёта отправителя
if (model.AccountSenderId < 0)
{
throw new ArgumentNullException("Отсутствие Id у счёта отправителя", nameof(model.AccountSenderId));
}
//проверка корректности Id счёта получателя
// Проверка корректности Id счёта получателя
if (model.AccountPayeeId < 0)
{
throw new ArgumentNullException("Отсутствие Id у счёта получателя", nameof(model.AccountPayeeId));
}
//проверка на корректную сумму перевода
// Проверка на корректную сумму перевода
if (model.Sum <= 0)
{
throw new ArgumentNullException("Сумма перевода не может раняться нулю или быть меньше его", nameof(model.Sum));
}
//проверка на корректную дату открытия счёта
// Проверка на корректную дату открытия счёта
if (model.DateTransfer > DateTime.Now)
{
throw new ArgumentNullException("Дата операции не может быть ранее текущей", nameof(model.DateTransfer));

View File

@ -17,11 +17,16 @@ namespace BankBusinessLogic.BusinessLogic.Client
public class CardLogic : ICardLogic
{
private readonly ILogger _logger;
private readonly ICardStorage _cardStorage;
private readonly IAccountLogic _accountLogic;
private readonly IDebitingLogic _debitingLogic;
private readonly ICreditingLogic _creditingLogic;
// Конструктор
public CardLogic(ILogger<CardLogic> logger, ICardStorage cardStorage, IAccountLogic accountLogic,
IDebitingLogic debitingLogic, ICreditingLogic creditingLogic)
{
@ -32,94 +37,135 @@ namespace BankBusinessLogic.BusinessLogic.Client
_creditingLogic = creditingLogic;
}
public bool Create(CardBindingModel model)
{
CheckModel(model);
if (_cardStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(CardBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_cardStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
// Вывод конкретной банковской карты
public CardViewModel? ReadElement(CardSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. CardNumber:{Number}.Id:{ Id}", model.Number, model.Id);
var element = _cardStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
// Вывод всего списка банковских карт
public List<CardViewModel>? ReadList(CardSearchModel? model)
{
_logger.LogInformation("ReadList. CardId:{Id}", model?.Id);
var list = model == null ? _cardStorage.GetFullList() : _cardStorage.GetFilteredList(model);
// list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _cardStorage.GetFullList() : _cardStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(CardBindingModel model)
// Создание банковской карты
public bool Create(CardBindingModel model)
{
CheckModel(model);
if (_cardStorage.Update(model) == null)
if (_cardStorage.Insert(model) == null)
{
_logger.LogWarning("Update operation failed");
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private void CheckModel(CardBindingModel model, bool withParams = true)
// Обновление банковской карты
public bool Update(CardBindingModel model)
{
CheckModel(model);
if (_cardStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
// Удаление банковской карты
public bool Delete(CardBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_cardStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(CardBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
// Так как при удалении передаём как параметр false
if (!withParams)
{
return;
}
// Проверка на наличие номера у банковской карты
if (string.IsNullOrEmpty(model.Number) || model.Number.Length != 16)
{
throw new ArgumentNullException("Неправильный номер карты", nameof(model.Number));
}
// Здесь стоит обсудить про баланс !!!!!! И про добавление ID клиента ниже!
// Проверка на конкретный период действия карты
if (model.Period < DateTime.Now)
{
throw new ArgumentNullException("Нет периода действия", nameof(model.Period));
}
var cardElement = _cardStorage.GetElement(new CardSearchModel
// Проверка на наличие id клиента, получеившего карту
if (model.ClientId < 0)
{
throw new ArgumentNullException("Некорректный Id кассира, открывшего счёт", nameof(model.ClientId));
}
// Для проверка на наличие такой же банковской карты
var cardElement = _cardStorage.GetElement(new CardSearchModel
{
Number = model.Number,
});
if (cardElement != null && cardElement.Id != model.Id)
// Если элемент найден и его Id не совпадает с Id переданного объекта
if (cardElement != null && cardElement.Id != model.Id)
{
throw new InvalidOperationException("Карта с таким ноиером уже есть");
}
@ -130,6 +176,7 @@ namespace BankBusinessLogic.BusinessLogic.Client
ClientId = model.ClientId
});
if (accountElement != null && accountElement.ClientId != model.ClientId)
{
throw new InvalidOperationException("Это не счёт данного клиента");

View File

@ -15,9 +15,12 @@ namespace BankBusinessLogic.BusinessLogic.Client
public class CreditingLogic : ICreditingLogic
{
private readonly ILogger _logger;
private readonly ICreditingStorage _creditingStorage;
private readonly ICardStorage _cardStorage;
// Конструктор
public CreditingLogic(ILogger<CreditingLogic> logger, ICreditingStorage creditingStorage, ICardStorage cardStorage)
{
_logger = logger;
@ -25,7 +28,50 @@ namespace BankBusinessLogic.BusinessLogic.Client
_cardStorage = cardStorage;
}
public bool Create(CreditingBindingModel model)
// Вывод конкретной операции на пополнение
public CreditingViewModel? ReadElement(CreditingSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. CreditingId:{ Id }", model.Id);
var element = _creditingStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
// Вывод всего списка операций на пополнение
public List<CreditingViewModel>? ReadList(CreditingSearchModel? model)
{
_logger.LogInformation("ReadList. CreditingId:{Id}", model?.Id);
// list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _creditingStorage.GetFullList() : _creditingStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
// Создание операции на пополнение
public bool Create(CreditingBindingModel model)
{
CheckModel(model);
@ -39,74 +85,64 @@ namespace BankBusinessLogic.BusinessLogic.Client
return true;
}
public bool Delete(CreditingBindingModel model)
// Обновление операции на пополнение
public bool Update(CreditingBindingModel model)
{
CheckModel(model);
if (_creditingStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
// Удаление операции на пополнение
public bool Delete(CreditingBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_creditingStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public CreditingViewModel? ReadElement(CreditingSearchModel model)
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(CreditingBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. CreditingId:{ Id }", model.Id);
var element = _creditingStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<CreditingViewModel>? ReadList(CreditingSearchModel? model)
{
_logger.LogInformation("ReadList. CreditingId:{Id}", model?.Id);
var list = model == null ? _creditingStorage.GetFullList() : _creditingStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(CreditingBindingModel model)
{
CheckModel(model);
if (_creditingStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(CreditingBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
// Так как при удалении передаём как параметр false
if (!withParams)
{
return;
}
if (model.Sum <= 0)
// Проверка на корректность Id банковской карты
if (model.ClientId < 0)
{
throw new ArgumentNullException("Некорректный Id счёта", nameof(model.ClientId));
}
// Проверка на корректность суммы пополнения
if (model.Sum <= 0)
{
throw new ArgumentNullException("Сумма операции должна быть больше 0", nameof(model.Sum));
}
if (model.DateCredit > DateTime.Now)
// Проверка на корректную дату операции
if (model.DateCredit > DateTime.Now)
{
throw new ArgumentNullException("Дата не может быть меньше текущего времени", nameof(model.DateCredit));
}
@ -114,6 +150,5 @@ namespace BankBusinessLogic.BusinessLogic.Client
_logger.LogInformation("Crediting. Sum:{Sum}.CardId:{CardId}.Date:{date}.Id:{Id}",
model.Sum, model.CardId, model.DateCredit.ToString(), model.Id);
}
}
}

View File

@ -20,6 +20,7 @@ namespace BankBusinessLogic.BusinessLogic.Client
private readonly ICardStorage _cardStorage;
// Конструктор
public DebitingLogic(ILogger<DebitingLogic> logger, IDebitingStorage debitingStorage, ICardStorage cardStorage)
{
_logger = logger;
@ -27,7 +28,50 @@ namespace BankBusinessLogic.BusinessLogic.Client
_cardStorage = cardStorage;
}
public bool Create(DebitingBindingModel model)
// Вывод конкретной операции на снятие наличных
public DebitingViewModel? ReadElement(DebitingSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. DebitingId:{ Id }", model.Id);
var element = _debitingStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
// Вывод всего списка операций на снятие наличных
public List<DebitingViewModel>? ReadList(DebitingSearchModel? model)
{
_logger.LogInformation("ReadList. DebitingId:{Id}", model?.Id);
// list хранит весь список в случае, если model пришло со значением null на вход метода
var list = model == null ? _debitingStorage.GetFullList() : _debitingStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
// Создание операции на снятие наличных
public bool Create(DebitingBindingModel model)
{
CheckModel(model);
@ -40,78 +84,70 @@ namespace BankBusinessLogic.BusinessLogic.Client
return true;
}
public bool Delete(DebitingBindingModel model)
// Обновление операции на снятие наличных
public bool Update(DebitingBindingModel model)
{
CheckModel(model);
if (_debitingStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
// Удаление операции на снятие наличных
public bool Delete(DebitingBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_debitingStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public DebitingViewModel? ReadElement(DebitingSearchModel model)
// Проверка входного аргумента для методов Insert, Update и Delete
private void CheckModel(DebitingBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. DebitingId:{ Id }", model.Id);
var element = _debitingStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<DebitingViewModel>? ReadList(DebitingSearchModel? model)
{
_logger.LogInformation("ReadList. DebitingId:{Id}", model?.Id);
var list = model == null ? _debitingStorage.GetFullList() : _debitingStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(DebitingBindingModel model)
{
CheckModel(model);
if (_debitingStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(DebitingBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
// Так как при удалении передаём как параметр false
if (!withParams)
{
return;
}
if (model.Sum <= 0)
// Проверка на корректность Id банковской карты
if (model.ClientId < 0)
{
throw new ArgumentNullException("Некорректный Id счёта", nameof(model.ClientId));
}
// Проверка на корректность снятия суммы
if (model.Sum <= 0)
{
throw new ArgumentNullException("Сумма операции должна быть больше 0", nameof(model.Sum));
}
_logger.LogInformation("Debiting. Sum:{Sum}.CardId:{CardId}.DateDebit:{DateDebit}.Id:{Id}",
// Проверка на корректную дату операции
if (model.DateDebit > DateTime.Now)
{
throw new ArgumentNullException("Дата не может быть меньше текущего времени", nameof(model.DateDebit));
}
_logger.LogInformation("Debiting. Sum:{Sum}.CardId:{CardId}.DateDebit:{DateDebit}.Id:{Id}",
model.Sum, model.CardId, model.DateDebit.ToString(), model.Id);
}
}

View File

@ -0,0 +1,16 @@
using BankBusinessLogic.OfficePackage.HelperEnums;
using BankBusinessLogic.OfficePackage.HelperModels;
using BankDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankBusinessLogic.OfficePackage.Implements
{
public class SaveToExcel
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankBusinessLogic.OfficePackage.Implements
{
public class SaveToPdf
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankBusinessLogic.OfficePackage.Implements
{
public class SaveToWord
{
}
}

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BankContracts\BankContracts.csproj" />
<ProjectReference Include="..\BankDatabaseImplement\BankDatabaseImplement.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,225 @@
using BankContracts.BindingModels.Cashier;
using BankContracts.BusinessLogicsContracts.Cashier;
using BankContracts.BusinessLogicsContracts.Client;
using BankContracts.SearchModels.Cashier;
using BankContracts.SearchModels.Client;
using BankContracts.ViewModels;
using BankContracts.ViewModels.Cashier.ViewModels;
using BankContracts.ViewModels.Client.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace BankRestAPI.Controllers
{
// Route будет строиться по наванию контроллера и по названию метода (два Post-метода)
[Route("api/[controller]/[action]")]
[ApiController]
public class AccountController : Controller
{
private readonly ILogger _logger;
private readonly IAccountLogic _accountLogic;
private readonly IDebitingLogic _debitingLogic;
private readonly ICreditingLogic _creditingLogic;
private readonly ICashWithdrawalLogic _cashwithdrawalLogic;
private readonly IMoneyTransferLogic _moneyTransferLogic;
// Конструктор
public AccountController(ILogger<AccountController> logger, IAccountLogic accountLogic, IDebitingLogic debitingLogic, ICreditingLogic creditingLogic, ICashWithdrawalLogic cashWithdrawalLogic, IMoneyTransferLogic moneyTransferLogic)
{
_logger = logger;
_accountLogic = accountLogic;
_debitingLogic = debitingLogic;
_creditingLogic = creditingLogic;
_cashwithdrawalLogic = cashWithdrawalLogic;
_moneyTransferLogic = moneyTransferLogic;
}
[HttpGet]
public AccountViewModel? Login(string accountNumber, string passwordAccount)
{
try
{
// Попытка найти счёт (запись) по переданным номеру и паролю счёта
return _accountLogic.ReadElement(new AccountSearchModel
{
AccountNumber = accountNumber,
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpGet]
public AccountViewModel? GetAccount(int accountId)
{
try
{
// Попробуем получить счёт
return _accountLogic.ReadElement(new AccountSearchModel
{
Id = accountId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpGet]
public List<AccountViewModel>? GetAllAccounts()
{
try
{
// Попробуем получить все имеющиеся счета
return _accountLogic.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpPost]
public void RegisterAccount(AccountBindingModel model)
{
try
{
// Создание счёта
_accountLogic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка регистрации счёта в банке");
throw;
}
}
[HttpPost]
public void UpdateData(AccountBindingModel model)
{
try
{
// Изменение данных о счёте
_accountLogic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления данных");
throw;
}
}
[HttpGet]
public List<AccountViewModel>? SearchAccounts(int cashierId)
{
try
{
// Поиск всех счетов которые сделал конкретный кассир
return _accountLogic.ReadList(new AccountSearchModel
{
CashierId = cashierId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "ОШбика входа в систему");
throw;
}
}
[HttpGet]
public List<AccountViewModel>? SearchAccountsOfClient(int clientId)
{
try
{
// Попытка найти запись по перданным номеру и паролю счета
return _accountLogic.ReadList(new AccountSearchModel
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "ОШибка входа в систему");
throw;
}
}
[HttpGet]
public List<CashWithdrawalViewModel>? FindAllCashWithdrawal()
{
try
{
return _cashwithdrawalLogic.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpGet]
public List<MoneyTransferViewModel>? FindAllMoneyTransfer()
{
try
{
return _moneyTransferLogic.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpGet]
public CreditingViewModel FindCrediting(int id)
{
try
{
// Поиск заявки на зачисление по id
return _creditingLogic.ReadElement(new CreditingSearchModel
{
Id = id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpGet]
public DebitingViewModel FindDebiting(int id)
{
try
{
// Поиск заявки на снятие по id
return _debitingLogic.ReadElement(new DebitingSearchModel
{
Id = id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
}
}

View File

@ -0,0 +1,126 @@
using BankContracts.BindingModels.Client;
using BankContracts.BusinessLogicsContracts.Cashier;
using BankContracts.BusinessLogicsContracts.Client;
using BankContracts.SearchModels.Client;
using BankContracts.ViewModels.Client.ViewModels;
using Microsoft.AspNetCore.Mvc;
using System.Net;
namespace BankRestAPI.Controllers
{
// Route будет строиться по наванию контроллера и по названию метода (два Post-метода)
[Route("api/[controller]/[action]")]
[ApiController]
public class CardController : Controller
{
private readonly ILogger _logger;
private readonly ICardLogic _cardLogic;
private readonly IDebitingLogic _debitingLogic;
private readonly ICreditingLogic _creditingLogic;
private readonly IAccountLogic _accountLogic;
// Конструктор
public CardController(ILogger<ClientController> logger, ICardLogic cardLogic, IDebitingLogic debitingLogic, ICreditingLogic creditingLogic, IAccountLogic accountLogic)
{
_logger = logger;
_cardLogic = cardLogic;
_debitingLogic = debitingLogic;
_creditingLogic = creditingLogic;
_accountLogic = accountLogic;
}
[HttpGet]
public List<CardViewModel>? GetAllCards()
{
try
{
return _cardLogic.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения карт");
throw;
}
}
[HttpGet]
public List<CardViewModel>? GetClientsCardsList(int id)
{
try
{
return _cardLogic.ReadList(new CardSearchModel()
{
ClientID = id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения карт");
throw;
}
}
[HttpPost]
public void CreateCard(CardBindingModel model)
{
try
{
_cardLogic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания банковской карты");
Response.StatusCode = (int)HttpStatusCode.NotAcceptable;
}
}
[HttpPost]
public void CreateDebitingRequest(DebitingBindingModel model)
{
try
{
_debitingLogic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания запроса на снятие наличных");
Response.StatusCode = (int)(HttpStatusCode.NotAcceptable);
}
}
[HttpPost]
public void CreateCreditingOperation(CreditingBindingModel model)
{
try
{
_creditingLogic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания операции на пополнение");
Response.StatusCode = (int)HttpStatusCode.NotAcceptable;
}
}
[HttpGet]
public CardViewModel? FindCard(int id)
{
try
{
return _cardLogic.ReadElement(new CardSearchModel
{
Id = id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
}
}

View File

@ -0,0 +1,94 @@
using BankContracts.BindingModels.Cashier;
using BankContracts.BusinessLogicsContracts.Cashier;
using BankContracts.BusinessLogicsContracts.Client;
using BankContracts.SearchModels.Cashier;
using BankContracts.ViewModels.Cashier.ViewModels;
using BankContracts.ViewModels.Client.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace BankRestAPI.Controllers
{
// Route будет строиться по наванию контроллера и по названию метода (два Post-метода)
[Route("api/[controller]/[action]")]
[ApiController]
public class CashierController : Controller
{
private readonly ILogger _logger;
private readonly ICashierLogic _cashierLogic;
// Конструктор
public CashierController(ICashierLogic cashierLogic, ILogger<AccountController> logger)
{
_logger = logger;
_cashierLogic = cashierLogic;
}
[HttpGet]
public CashierViewModel? Login(string login, string password)
{
try
{
// Попытка найти кассира (запись) по переданным логину и паролю
return _cashierLogic.ReadElement(new CashierSearchModel
{
Email = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpGet]
public CashierViewModel? GetCashier(int id)
{
try
{
// Попытка найти кассира
return _cashierLogic.ReadElement(new CashierSearchModel
{
Id = id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpPost]
public void Register(CashierBindingModel model)
{
try
{
// Cоздание кассира
_cashierLogic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка регистрации");
throw;
}
}
[HttpPost]
public void UpdateData(CashierBindingModel model)
{
try
{
// Изменение данных о кассире
_cashierLogic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления данных");
throw;
}
}
}
}

View File

@ -0,0 +1,146 @@
using BankContracts.BindingModels.Client;
using BankContracts.BusinessLogicsContracts.Client;
using BankContracts.SearchModels.Client;
using BankContracts.ViewModels.Client.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace BankRestAPI.Controllers
{
// Route будет строиться по наванию контроллера и по названию метода (два Post-метода)
[Route("api/[controller]/[action]")]
[ApiController]
public class ClientController : Controller
{
private readonly ILogger _logger;
private readonly IClientLogic _clientLogic;
private readonly IDebitingLogic _debitingLogic;
private readonly ICreditingLogic _creditingLogic;
// Конструктор
public ClientController(ILogger<ClientController> logger, IClientLogic clientLogic, IDebitingLogic debitingLogic, ICreditingLogic creditingLogic)
{
_logger = logger;
_clientLogic = clientLogic;
_debitingLogic = debitingLogic;
_creditingLogic = creditingLogic;
}
[HttpGet]
public ClientViewModel? Login(string login, string password)
{
try
{
// Попытка найти клиента (запись) по переданным логину и паролю
return _clientLogic.ReadElement(new ClientSearchModel
{
Email = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpGet]
public List<ClientViewModel>? GetAllClients()
{
try
{
return _clientLogic.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения пользователя");
throw;
}
}
[HttpGet]
public ClientViewModel? GetClient(int clientId)
{
try
{
// Попытка найти клиента
return _clientLogic.ReadElement(new ClientSearchModel
{
Id = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения пользователя");
throw;
}
}
[HttpPost]
public void Register(ClientBindingModel model)
{
try
{
// Создание клиента
_clientLogic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка регистрации");
throw;
}
}
[HttpPost]
public void UpdateData(ClientBindingModel model)
{
try
{
// Изменение данных о клиенте
_clientLogic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления данных");
throw;
}
}
[HttpGet]
public List<DebitingViewModel>? getClientsDebitings(int clientId)
{
try
{
return _debitingLogic.ReadList(new DebitingSearchModel()
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения пользователей");
throw;
}
}
[HttpGet]
public List<CreditingViewModel>? getClientsCreditings(int clientId)
{
try
{
return _creditingLogic.ReadList(new CreditingSearchModel()
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения пользователей");
throw;
}
}
}
}

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
namespace BankRestAPI.Controllers
{
public class ReportController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

View File

@ -0,0 +1,31 @@
var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config");
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5946",
"sslPort": 44353
}
},
"profiles": {
"BankRestAPI": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7194;http://localhost:5164",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:/temp/BlacksmithWorkshopResrApi.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
</layout>
</appender>
<root>
<level value="TRACE" />
<appender-ref ref="RollingFile" />
</root>
</log4net>