-
Notifications
You must be signed in to change notification settings - Fork 1
/
dci_money_transfer.cs
103 lines (88 loc) · 2.75 KB
/
dci_money_transfer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System.Collections;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Shpec;
using Shpec.Declare;
namespace Playground.UseCases
{
using DCI.MoneyTransfer;
// Data Context Interaction (https://en.wikipedia.org/wiki/Data,_context_and_interaction)
// Referenced C# Example (https://github.com/programmersommer/DCISample)
// Money Transfer Example
public class dci_money_transfer : IUseCase
{
public void Execute()
{
var bank = new Bank();
bank.Set(new Account(1, 100));
bank.Set(new Account(2, 10));
var ctx = new MoneyTransferContext(bank, 1, 2);
ctx.Transfer(50);
Debug.Assert(bank.Get(1).Amount == 50, "subtracted money from source account");
Debug.Assert(bank.Get(2).Amount == 60, "added money from source account");
}
}
}
namespace Playground.UseCases.DCI.MoneyTransfer
{
public class TestMembers
{
public static int AccountId = Member<int>.Property();
public static int Amount = Member<int>.Property();
[MethodDefinition]
public static void AddFunds(int amount)
{
Amount += amount;
}
[MethodDefinition]
public static void SubtractFunds(int amount)
{
Amount -= amount;
}
}
public partial class Account
{
Members _m => new(AccountId, Amount);
}
public class Bank
{
private readonly Dictionary<int, Account> _accounts = new() { };
public Account Get(int id) => _accounts[id];
public void Set(Account account) => _accounts[account.AccountId] = account;
}
public partial class MoneyTransferContext
{
public MoneyTransferContext(Bank bank, int sourceId, int destinationId)
{
SourceAccount = bank.Get(sourceId);
DestinationAccount = bank.Get(destinationId);
}
public void Transfer(int amount)
{
SourceAccount.Transfer(amount);
}
public partial interface ISourceAccount
{
Members _m => new(AccountId, Amount, SubtractFunds);
public void Transfer(int amount)
{
if (Amount < amount)
{
throw new InvalidOperationException("insufficient funds");
}
SubtractFunds(amount);
// interact
Context.DestinationAccount.Transfer(amount);
}
}
public partial interface IDestinationAccount
{
Members _m => new(Amount, AddFunds);
public void Transfer(int amount)
{
// interact
AddFunds(amount);
}
}
}
}