Round #511
09 May 2026, 20:05· csharp· qwen2.5-coder-7b-instruct· r13-clean-hints
- Complexity
- band 0
- ZP / UO / OBS
- 6 / 0 / 0
- Journey weight
- 438
- Lightshift ΔL
- +0.50
Prompt
Implement a business rule validator that checks account balance before transfer
Zero-point index (what the engine surfaced)
ZPI-ZPI-0020 | 2026-05-09T20:05:16Z
Implement a business rule validator that checks account balance before transfer
ZERO POINT — 6 entries (structural invariants)
● hsl(159.80, 100%, 27%) IValidator<T> [contract]
● hsl(240.67, 100%, 27%) AbstractValidator<T> [contract]
● hsl(175.80, 100%, 27%) IValidatableObject [contract]
● hsl(328.68, 100%, 27%) IValidatorFactory [contract]
● hsl(145.31, 100%, 27%) ValidationResult [contract]
● hsl(39.29, 100%, 27%) ValidationContext<T> [contract]
UNOBSERVED — 0 entries (implied truths)
OBSERVED — 0 entries (explicit in request)
COMPLEXITY │ 6 entries │ spread: 0° │ band: LOW
Baseline response (no ZPI)
Certainly! Below is an example of how you can implement a business rule validator in C# to check the account balance before transferring funds between two accounts.
First, let's define some classes for our accounts:
```csharp
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Balance { get; set; }
public Account(int id, string name, decimal balance)
{
Id = id;
Name = name;
Balance = balance;
}
public void Transfer(Account toAccount, decimal amount)
{
if (amount <= 0)
{
throw new ArgumentException("Transfer amount must be greater than zero.");
}
if (!Validator.CheckBalance(this, amount))
{
throw new InvalidOperationException("Insufficient funds for transfer.");
}
this.Balance -= amount;
toAccount.Balance += amount;
Console.WriteLine($"Transferred {amount} from {this.Name} to {toAccount.Name}");
}
}
```
Next, let's create a validator class that will check the account balance:
```csharp
public static class Validator
{
public static bool CheckBalance(Account account, decimal amount)
{
return account.Balance >= amount;
}
}
```
Now, you can use these classes to perform transfers while ensuring that the transfer is only allowed if there are sufficient funds in the source account:
```csharp
class Program
{
static void Main(string[] args)
{
Account account1 = new Account(1, "John Doe", 1000m);
Account account2 = new Account(2, "Jane Smith", 500m);
try
{
account1.Transfer(account2, 300m); // Valid transfer
account1.Transfer(account2, 600m); // Invalid transfer due to insufficient funds
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
```
In this example:
- The `Account` class has a method `Transfer` that checks if the transfer amount is valid and if there are sufficient funds in the source account using the `Validator.CheckBalance` method.
- If the balance check fails, an `InvalidOperationException` is thrown with an appropriate message.
This approach ensures that all transfers are validated before being executed, preventing any invalid transactions due to insufficient funds.
Enhanced response (with ZPI)
To implement a business rule validator that checks the account balance before transferring funds, we can use the `IValidator<T>` contract from the FluentValidation library. This approach provides a flexible and powerful way to define validation rules for our domain models.
First, let's install the FluentValidation package via NuGet:
```sh
dotnet add package FluentValidation
```
Next, we'll create a domain model representing an account and a validator for it.
### Domain Model
```csharp
public class Account
{
public int Id { get; set; }
public decimal Balance { get; set; }
public void Transfer(decimal amount)
{
if (amount <= 0)
throw new ArgumentException("Transfer amount must be greater than zero.");
if (Balance < amount)
throw new InvalidOperationException("Insufficient funds.");
Balance -= amount;
}
}
```
### Validator
```csharp
using FluentValidation;
public class AccountValidator : AbstractValidator<Account>
{
public AccountValidator()
{
RuleFor(account => account.Balance).NotEmpty().WithMessage("Account balance cannot be empty.");
RuleFor(account => account.Balance).GreaterThan(0).WithMessage("Account balance must be greater than zero.");
}
}
```
### Usage
```csharp
using FluentValidation.Results;
public class AccountService
{
private readonly IValidator<Account> _accountValidator;
public AccountService(IValidator<Account> accountValidator)
{
_accountValidator = accountValidator;
}
public void Transfer(Account fromAccount, Account toAccount, decimal amount)
{
var validationResultFrom = _accountValidator.Validate(fromAccount);
if (!validationResultFrom.IsValid)
throw new ValidationException(validationResultFrom.Errors);
var validationResultTo = _accountValidator.Validate(toAccount);
if (!validationResultTo.IsValid)
throw new ValidationException(validationResultTo.Errors);
fromAccount.Transfer(amount);
}
}
```
### Dependency Injection Registration
```csharp
using Microsoft.Extensions.DependencyInjection;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IValidator<Account>, AccountValidator>();
services.AddScoped<AccountService>();
}
}
```
### Explanation
1. **Domain Model (`Account`)**:
- The `Account` class represents an account with a balance and a method to transfer funds.
- The `Transfer` method includes validation logic to ensure the amount is greater than zero and that there are sufficient funds.
2. **Validator (`AccountValidator`)**:
- The `AccountValidator` class inherits from `AbstractValidator<Account>` and defines rules for the account balance.
- It ensures that the balance is not empty and is greater than zero.
3. **Service (`AccountService`)**:
- The `AccountService` class uses an instance of `IValidator<Account>` to validate both the source and destination accounts before performing a transfer.
- If any validation fails, it throws a `ValidationException` with the error details.
4. **Dependency Injection**:
- In the `Startup` class, we register the `AccountValidator` as a transient service and the `AccountService` as a scoped service.
- This setup ensures that each request for an `AccountService` gets its own instance of the validator.
This implementation provides a clear separation of concerns, with validation logic encapsulated in the validator and business logic in the service. It also leverages dependency injection to manage dependencies, making the code more testable and maintainable.
Grader chain
Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.
V1samba/Meta-Llama-3.3-70B-Instruct
BetterV4qwen2.5-coder-3b-instruct
BetterV5openrouter/qwen/qwen3-235b-a22b-2507
BetterV7qwen2.5-coder-7b-instruct
BetterV8openai/gpt-4.1
BetterV9anthropic/claude-opus-4-7
BetterV12openai/gpt-4o
BetterComments
Our grader said what it said. What do you say? Comment as a guest below.
No comments yet. Be the first to say what you make of this round.