Recently, I struggled trying to figure out if some methods, functions in my architecture was at the good place; in the correct layer. I want to follow the repository pattern of Martin Fowler to decouple my service layer from the database.
The definition explained by Martin Fowler on his web site, say:
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
The problem is that I have a lot of requirements where I must get for example the sum of all invoices. As you can understand, the sum of all invoices is a scalar value. If I follow the definition of Martin Fowler, what I should do is create a function that returns a list of domain objects from my repository layer that is receive by the service layer which loop throw the objects to calculate the total. It is also possible that I don't understand the essence of what this pattern means...
I know that performance should not be a concern while designing the application because maintainability is better but in the case, it's in my view a complete waste of time in development and performance to not create a function in the repository layer that returns a decimal value that correspond to the total of invoices and returns this same value from the service layer. Materializing a list of objects and then just using a single property is an overkill even if you can add some lazy loading strategy with an ORM.
Is it correct to return scalar value from the repository layer or should I resist to the temptation and always returns domain object(s) from this layer and process all the business logic in the service layer?
I also have a lot of places where my presenters calls directly my repository instead of calling the service layer which then call the repository layer. It is correct; acceptable to call this repository pattern outside of the service layer?
Note that I don't want to return a IQueryable result from my repository layer because this will be in total contradiction with the Law of Demeter.
Also, I don't want to set the query directly in my service layer because I want to be able to completely unit testing this layer; not doing integration test.