Thinking about repositories
For a long time, I have used the idea of IRepository<T> as my main data access method.
It is a very good approach, and I have used a static gateway to be able to resolve that effectively. The code to use that read like this:
Repository<Account>.Save(account);
But, I have an issue with that, because this is an opque dependency. I don't have a way to look at the declaration and just get what this needs. It makes testing a lot harder than it should be, because you now need to do indirect dependency injection.
There is the additional problem of the actual IRepository<T> interface:

That is an interface with 40 methods. And most of those methods are dealing directly with the data access code.
When I first to move away from this approach, I started to inject the IRepository<Account> into my services, which worked well. The code looked like this:
public class AccountService
{
public AccountService(IRepository<Account> accountsRepository)
{
//...
}
}
The problem with that is readability, take a look at the usage:
accountsRepository.FindAll(
Where.Account.LastActivity < DateTime.Now.AddDays(-60)
);
Can you tell me what the meaning of this is? It express what it is doing really well, I think, but not what the meaning of it.
So, I started with the idea that I have domain repositories and infrastructure repositories. So I introduced this interface:
And then I can call:
accountsRepository.FindAllInvactiveAccounts()
I didn't really like that, because infrastracture repository doesn't really sit well with me. There is another issue, which is the implementation of IAccountsRepository implementation:
I have the IAccountRepository depending on IRepository<Account>, but that is... a smell. Then I thought about this approach:
But that doesn't sit very well with me either.
Eventually, I got to this design:
accountsRepository.FindAll(
new InactiveAccountQuery()
);
Where the accountsRepository is a IRepository<Account> implementation. A better syntax for that is probably this:
accountsRepository.FindAll(
Accounts.Inactive
);
That looks much better, and where I am going to stop for now