First, to really answer your question, it is important to know why you need to get all user accounts? You:
- Getting a list of accounts to display on the screen for the user. then execute a command / transaction on a single account?
- Executing a single command / transaction for all user accounts - for example, "Block all user accounts"?
The reason I'm asking for is because you only need to consider the DDD aspect if it is the latter. If the reason for this "functionality" is the first (and after reading your question, I suspect that it is) - I really recommend just creating a thin layer of a query service that receives the user account information needed for the screen. You do not need to add DDD "restrictions" for this; No transactions or model state changes. Providing this functionality does not have to include a domain model . Simply define a simple POCO DTO and use the Entity Framework to retrieve data and transfer it back to the user interface.
This is what CQRS is about; you donโt need repositories, factories, or aggregates to give the user interface a list of user accounts to choose from - you would complicate it and make A LOT more for yourself.
If there is a scenario requiring a single transaction across all user accounts, I would do something like:
public class AccountService : IAccountService { private IAccountRepository _accountRespository; public void FreezeAllAccountsForUser(Guid userId) { IEnumerable<IAccount> accounts = _accountRespository.GetAccountsByUserId(userId); using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create()) { foreach (IAccount account in _accounts) { account.Freeze(); _accountRespository.Save(account); } } } }
Where AccountService is a web service, i.e. an application tier.
In conclusion, my advice is: consider only DDD in the context of commands for which transactions are required. To select data lists; create a simple query service that the user interface can use.
PS I noticed the misuse of the Factory pattern in your question and some answers. Factories are intended to provide a strategy for CREATING an object, taking into account specific data. There should not be a GetAccount (accountId) method that calls the database; repositories invoke the database and then pass the data to Factory to create the object.
source share