Dependency Inversion Principle (DIP)

The Dependency Inversion Principle (DIP) states that high-level modules should not depend on low-level modules. Both should depend on abstractions. Also, abstractions should not depend on details. Details should depend on abstractions.

Bad Example:

A `Application` class depends directly on a `MySQLDatabase` class. This violates the DIP because the high-level module (`Application`) depends directly on a low-level module (`MySQLDatabase`).

                    
                    class MySQLDatabase {
                        public void Save(object obj) {
                            // Save object in MySQL database...
                        }
                    }

                    class Application {
                        private MySQLDatabase _db;

                        public Application() {
                            _db = new MySQLDatabase();
                        }

                        public void Save(object obj) {
                            _db.Save(obj);
                        }
                    }
                    
                    

Corrected Example:

A better design would be to introduce an abstraction (`IDatabase`) and make both the high-level module (`Application`) and the low-level module (`MySQLDatabase`) depend on this abstraction.

                    
                    interface IDatabase {
                        void Save(object obj);
                    }

                    class MySQLDatabase : IDatabase {
                        public void Save(object obj) {
                            // Save object in MySQL database...
                        }
                    }

                    class Application {
                        private IDatabase _db;

                        public Application(IDatabase db) {
                            _db = db;
                        }

                        public void Save(object obj) {
                            _db.Save(obj);
                        }
                    }