One, if not the main, principle of the good architecture is its openness against 'possible' changes. It can be viewed on different abstraction levels - some classes can be open for some changes in business logic, entire layers may be designed to be open for global changes like switching to another DB engine. As OCP states, entities should be open for extension, but not for modification. This means that your architecture should support its extension in planned ways easily without changing much code (you should write new of course). That is why seasoned developer likes to use interfaces here and there :-) And that is what dependency injection is for...
It’s a good practice to build Data Access layer in a way it is not tied to specific database. So if you use SQL server and then decide to use Oracle, you need to write new Data Access classes specific to Oracle and do not need to rewrite entire system.
I was surprised, but it turns out that you can isolate user interface logic for web project in the same way.