Aufgaben-Python/courses/csharp/12_exception_handling_und_ressourcen/Aufgabe.cs

139 lines
5.1 KiB
C#

using System;
using System.Collections.Generic;
namespace CSharpKurs.Modul12;
// ============================================================================
// 🎯 TODO 1: Domain-Exceptions
// Erstelle die Exception-Hierarchie für das Bankensystem:
// - BankDomainException (erbt von Exception) mit Property 'string ErrorCode'
// - AccountNotFoundException (erbt von BankDomainException) mit Property 'Guid AccountId'
// - InsufficientFundsException (erbt von BankDomainException) mit 'Guid AccountId', 'decimal RequestedAmount', 'decimal CurrentBalance'
// ============================================================================
public class BankDomainException : Exception
{
public string ErrorCode { get; }
public BankDomainException(string message, string errorCode = "BANK_ERROR")
: base(message)
{
ErrorCode = errorCode;
}
}
public class AccountNotFoundException : BankDomainException
{
public Guid AccountId { get; }
public AccountNotFoundException(Guid accountId)
: base($"Konto mit ID '{accountId}' wurde nicht gefunden.", "ACCOUNT_NOT_FOUND")
{
// TODO 1a: Setze AccountId
throw new NotImplementedException();
}
}
public class InsufficientFundsException : BankDomainException
{
public Guid AccountId { get; }
public decimal RequestedAmount { get; }
public decimal CurrentBalance { get; }
public InsufficientFundsException(Guid accountId, decimal requestedAmount, decimal currentBalance)
: base($"Konto '{accountId}' verfügt nicht über ausreichend Guthaben. Verfügbar: {currentBalance}, Angefordert: {requestedAmount}", "INSUFFICIENT_FUNDS")
{
// TODO 1b: Setze AccountId, RequestedAmount und CurrentBalance
throw new NotImplementedException();
}
}
// ============================================================================
// 🎯 TODO 2: IDisposable Resource Management
// ============================================================================
public class AuditTransactionScope : IDisposable
{
private bool _disposed = false;
public string TransactionId { get; }
public List<string> LogEntries { get; } = new();
public bool IsDisposed => _disposed;
public AuditTransactionScope(string transactionId)
{
TransactionId = transactionId;
LogEntries.Add($"Scope gestartet für TX {transactionId}");
}
public void Record(string message)
{
// TODO 2a: Wenn _disposed == true ist, wirf eine ObjectDisposedException(nameof(AuditTransactionScope)).
// Andernfalls füge die Nachricht zur LogEntries-Liste hinzu.
throw new NotImplementedException();
}
public void Dispose()
{
// TODO 2b: Wenn noch nicht disposed, füge "Scope beendet für TX {TransactionId}" zu LogEntries hinzu
// und setze _disposed auf true.
throw new NotImplementedException();
}
}
// ============================================================================
// 🎯 TODO 3: BankAccount Entität
// ============================================================================
public class BankAccount
{
public Guid Id { get; }
public string Owner { get; }
public decimal Balance { get; private set; }
public BankAccount(Guid id, string owner, decimal initialBalance = 0m)
{
if (initialBalance < 0)
throw new ArgumentOutOfRangeException(nameof(initialBalance), "Startguthaben darf nicht negativ sein.");
Id = id;
Owner = owner;
Balance = initialBalance;
}
public void Deposit(decimal amount)
{
// TODO 3a: Wenn amount <= 0, wirf eine ArgumentOutOfRangeException.
// Andernfalls erhöhe Balance um amount.
throw new NotImplementedException();
}
public void Withdraw(decimal amount)
{
// TODO 3b: Wenn amount <= 0, wirf ArgumentOutOfRangeException.
// Wenn amount > Balance, wirf eine InsufficientFundsException(Id, amount, Balance).
// Andernfalls ziehe amount von Balance ab.
throw new NotImplementedException();
}
}
// ============================================================================
// 🎯 TODO 4: BankTransferService
// ============================================================================
public class BankTransferService
{
private readonly Dictionary<Guid, BankAccount> _accounts = new();
public void RegisterAccount(BankAccount account)
{
ArgumentNullException.ThrowIfNull(account);
_accounts[account.Id] = account;
}
public void TransferFunds(Guid fromId, Guid toId, decimal amount, out List<string> auditLogs)
{
// TODO 4:
// 1. Initialisiere using var scope = new AuditTransactionScope($"TX-{Guid.NewGuid():N}");
// 2. Finde Quell- und Zielkonto. Wenn nicht vorhanden, wirf AccountNotFoundException.
// 3. Buche amount von fromAccount ab (Withdraw) und buche auf toAccount auf (Deposit).
// 4. Protokolliere erfolgreiche Buchung mit scope.Record($"Überwiesen: {amount} von {fromId} an {toId}");
// 5. Gib scope.LogEntries über den out-Parameter auditLogs zurück.
throw new NotImplementedException();
}
}