What is the best way to actually implement service classes when following domain driven design?
For example say I want to have an AccountService
which can be used to transfer funds from one account to another? Which of the following, if any, would be the best way to implement this?
public class AccountService1
{
private IAccountRepository _accountRepo;
public AccountService1(IAccountRepository accountRepo)
{
_accountRepo = accountRepo;
}
public void TransferFunds(double ammount, int sourceAccountNumber, int targetAccountNumber)
{
//FUNDS TRANSFER CODE
}
}
public class AccountService2
{
public void TransferFunds(double ammount, Account sourceAccount, Account targetAccount)
{
//FUNDS TRANSFER CODE
}
}
public static class AccountService3
{
public static void TransferFunds(double amount, Account sourceAccount, Account targetAccount)
{
//FUNDS TRANSFER CODE
}
}
public static class AccountService4
{
public static void TransferFunds(double amount, int sourceAccountNumber, int targetAccountNumber, IAccountRepository repository)
{
//FUNDS TRANSFER CODE
}
}
Your first implementation is the best option. However, you should also implement a Transfer method on the Account class itself which accepts an amount and a target Account instance as well. The role of the service in this case is to load Account instances using the repository, save them, unit of work management, as well as providing access to any external services that may be needed. The role of the Transfer method on the Account class is to protect the integrity of the data within the Account class itself and ensure consistency, throw exceptions etc.
class Account {
public string State { get; private set; }
public decimal Total { get; private set; }
public void Transfer(decimal amount, Account dest) {
if (amount > this.Total) throw Exception();
if (this.State == "Closed") throw Exception();
this.Total -= amount;
dest.Total += amount;
}
}
So the Account class defines what operations are possible and the service layer is what operates upon the domain layer and is thus concerned with all operational responsibilities.