Logically how can I prevent a client from making changes to a domain model entity if a service is not used? For example:
Let's say I have an Account class that contains Transactions to compute a balance. A service is used to coordinate the interaction of these entities. However, I only want a client to be able to use specific functions (e.g. CurrentBalance, BalanceByDate(), etc.). I do not want to allow them access to AddTransaction without using the service. A DTO seems odd since it's not really transitioning boundaries.
Account
public class Account
{
public decimal CurrentBalance()
{
// return current balance
}
public decimal BalanceByDate(DateTime date)
{
// return balance through date
}
// Want to restrict usage of this to a service only
// to coordinate interaction of multiple entities to
// prevent corruption to the accounting system
public void AddTransaction(Transaction trans)
{
// add transaction to list of transactions
}
}
AccountingService
public class AccountingService
{
public void AddTransaction(Transaction trans)
{
foreach (var account in trans.Accounts)
account.AddTransaction(trans); // method in question
}
public Account GetAccount(int ID)
{
// return account by id
}
}
Client
var accountingService = new AccountingService();
// build transaction here
var transaction = TransactionFactory.Create(/*blah*/);
accountingService.AddTransaction(transaction);
// but this would be harmful to the system...
var account = accountingService.GetAccount(accountID);
account.AddTransaction(new Transaction(/*junk data*/));
// however, still want to get the balance of the account
var balance = account.CurrentBalance();
So how do most people handle this? Expose different interfaces so clients use something different? Have Account implement IAccountable vs ITransactionable? Or just return some type of read-only Account where calling AddTransaction() really only affects that object? Another idea was to inject a list of transactions into the Account constructor and remove the AddTransaction() method.