Jul 12, 2014 04:48 AM|jammycakes|LINK
As I've already said, if you want to tightly couple your layers together due to the benefits it supplies then that's up to you. If you want to dismiss the issues that will cause when layers need to move then that's up to you too.
And as I've already said, my point is not that you shouldn't decouple your layers in the way you're suggesting, but that you
can't. Yes, you may implement something that looks like a nice neat separation of concerns, but if you actually try to swap out one data source for another in the way you've suggested, you'll quickly find that you almost certainly
haven't separated your concerns out as well as you think you have. You have to consider behaviour as well as just method signatures and interface implementations, and that is where it all gets messy.
The fact of the matter is that unless the projects you are working on are all very simple, you
will need to control lazy loading, access transactions, shape queries, handle cross-cutting concerns, batch updates and deletes, manage concurrency, and do a whole lot of other things like that in your business layer that require direct access
to more advanced features of your ORM. Take query shaping for instance -- the most obvious (and simple) example here is filtering, paging and sorting data for display in a table. If you're insisting on putting ToList() in your repository, you're either going
to end up with terrible performance (because you're returning masses and masses of data that you don't need) or else you're effectively moving your business logic into your repository, and you'll end up with an Anaemic Business Layer that doesn't do anything
except shunt data from one anaemic domain model to another identical anaemic domain model -- and if you're doing that, then what's the point of having a separate business layer in the first place?
So to answer the OP's question, the best place to put ToList() is in your business layer, if in fact you use ToList() at all. It shouldn't be automatic: it really needs to be treated on a case by case basis.
As for moving the layers or swapping out your data source, I've cried "architecture astronaut" here because these are scenarios that I've seen repeated parrot fashion time and time again over the past twelve or so years that I've been working with .net,
with little or no discussion as to whether (a) you're actually going to have to face them in the first place (you usually aren't), or (b) the "best practices" that you're following actually facilitate them in reality without introducing more problems than
they solve (they usually don't). In actual fact, when you do need to scale out, it's never as simple in practice as shifting your presentation layer onto a separate server and sticking a service in between. You usually have to adopt other approaches such as
caching, or sharding, or moving whole chunks of functionality into a separate application altogether, or switching from a traditional layered architecture to a CQRS/Event Sourcing one.