Inyección de dependencia

Las interfaces nos permiten desacoplar las funciones al no depender de una clase, sino de la implementación de un interfaz:

https://anexsoft.com/ejemplo-de-inyeccion-de-dependencias-con-c

Definición:

https://www.freecodecamp.org/news/a-quick-intro-to-dependency-injection-what-it-is-and-when-to-use-it-7578c84fa88f/

https://www.dotnettricks.com/learn/dependencyinjection/implementation-of-dependency-injection-pattern-in-csharp

Gente que está en contra (en ocasiones):

Las ventajas de NO usar inyección de dependencias

Otro ejemplo polimorfismo

 class Persona
    {
        private string _nombre;

        public Persona(string nombre)
        {
            Console.WriteLine("Constructor persona " + nombre);
            this.Nombre = nombre;
        }
        public string Nombre
        {
            set { this._nombre = value; }
            get { return this._nombre; }
        }
        public virtual string saludo()
        {
            return "Hola "+Nombre+" que tal";
        }
      
    }

    class Empleado :Persona
    {
        public Empleado(string nombre, int sueldo=0) : base(nombre)
        {
            Console.WriteLine("Constructor empleado " + nombre);

            this.Cargo = "Empleado";
        }
        public int Sueldo { get; set; }
        private string _cargo;
        public string Cargo {
            set { this._cargo = value; }
            get { return this._cargo; } }
        public override string saludo()
        {
            return "Hola empleado " + Nombre + " ¿Todo bien?";
        }
        public virtual double sueldoNeto()
        {
            return Sueldo * .85;
        }
       
    }
    class Gerente : Empleado
    {
        public int Bono { get; set; }
        public int Dietas { get; set; }
        public Gerente(string nombre) : base(nombre)
        {
            Console.WriteLine("Constructor gerente " + nombre);

            this.Cargo = "Gerente";

        }

        public Gerente(string nombre, int sueldo) : base(nombre, sueldo) { }
        public Gerente(string nombre, int sueldo, int dietas) : this(nombre, sueldo)
        {
            Dietas = dietas;
        }
        public override string saludo()
        {
            return "Hola Sr. " + Nombre + " ¿Desea alguna cosa?";
        }
        public override double sueldoNeto()
        {
            return base.sueldoNeto()+Dietas;
        }
    }
    sealed class Direccion : Gerente
    {
        public int StockOptions { get; set; }
        public Direccion(string nombre) : base(nombre, 100) {
            Console.WriteLine("Constructor direccion " + nombre);
        }
        public Direccion(string nombre, int sueldo) : base(nombre, sueldo) { }
        public Direccion(string nombre, int sueldo, int dietas):base(nombre, sueldo, dietas) { }
        public Direccion(string nombre, int sueldo, int dietas, int stockoptions) : this(nombre, sueldo, dietas)
        {
            this.StockOptions = stockoptions;
        }
        public override string saludo()
        {

            return "Buenos días Sr. " + Nombre + " Estamos a sus órdenes";
        }
        public override double sueldoNeto()
        {
            return base.sueldoNeto()+StockOptions*.5;
        }
    }
    class Cliente : Persona
    {
        public Cliente(string nombre) : base(nombre)
        {
        }
    }

Uso:

  Empleado eva = new Empleado("Eva",1200);
         
           
            Gerente ana = new Gerente("Ana");
            ana.Sueldo = 1700;
            ana.Dietas = 200;
            Direccion rosa = new Direccion("Rosa");
            rosa.Sueldo = 2500;
            rosa.Dietas = 300;
            rosa.StockOptions = 100;
            Console.WriteLine(rosa.sueldoNeto());
            Empleado[] plantilla = { eva, ana, rosa };
            double total = 0;
            foreach(Empleado item in plantilla)
            {
                total += item.sueldoNeto();
            }
            Console.WriteLine(total);

Herencia en c# y polimorfismo

 class Persona
    {
        private string _nombre;

        public Persona(string nombre)
        {
            Console.WriteLine("Constructor persona " + nombre);
            this.Nombre = nombre;
        }
        public string Nombre
        {
            set { this._nombre = value; }
            get { return this._nombre; }
        }
        public virtual string saludo()
        {
            return "Hola "+Nombre+" que tal";
        }

    }

    class Empleado :Persona
    {
        public Empleado(string nombre) : base(nombre)
        {
            Console.WriteLine("Constructor empleado " + nombre);

            this.Cargo = "Empleado";
        }
        private string _cargo;
        public string Cargo {
            set { this._cargo = value; }
            get { return this._cargo; } }
        public override string saludo()
        {
            return "Hola empleado " + Nombre + " ¿Todo bien?";
        }

    }
    class Gerente : Empleado
    {
        public int Bono { get; set; }
        public Gerente(string nombre) : base(nombre)
        {
            Console.WriteLine("Constructor gerente " + nombre);

            this.Cargo = "Gerente";

        }
        public Gerente(string nombre, int bono) : this(nombre)
        {
            this.Bono = bono;

        }
        public override string saludo()
        {
            return "Hola Sr. " + Nombre + " ¿Desea alguna cosa?";
        }
    }
    sealed class Direccion : Gerente
    {
        public Direccion(string nombre) : base(nombre, 100) {
            Console.WriteLine("Constructor direccion " + nombre);
        }
        public override string saludo()
        {
            return "Buenos días Sr. " + Nombre + " Estamos a sus órdenes";
        }
    }

Ejemplo de uso:

  Persona[] plantilla = { new Persona("Eva"), new Empleado("Juan"),new Empleado("Ana"),
            new Gerente("Rosa"), new Gerente("Luis"), new Direccion("Laura")};
            foreach(Persona empleado in plantilla)
            {
                Console.WriteLine(empleado.saludo());
            }

Clase Empleado

 class Empleado
    {
        private string pNombre;
        private string pDni;
        private decimal pSueldo;

        public string Nombre
        {
            get
            {
                return pNombre;
            }
            set
            {
                    Console.WriteLine("Set de nombre");
                if (value.Length < 3)
                {
                    throw new Exception("El nombre debe tener una longitud mayor de 3");
                }
                else
                {
                    this.pNombre = value;
                }
            }
        }
        public string Dni
        {
            get { return this.pDni; }
            set { this.pDni = value; }
        }
        public decimal Sueldo
        {
            get { return this.pSueldo; }
            set { this.pSueldo = value; }
        }
        public Empleado(string nombre)
        {
            Console.WriteLine("Constructor 1");
            this.Nombre = nombre;
        }
        public Empleado(string nombre, string dni) : this(nombre)
        {
            Console.WriteLine("Constructor 2");
            this.Dni = dni;
        }
        public Empleado(string nombre, string dni, decimal sueldo) : this(nombre, dni)
        {
            Console.WriteLine("Constructor 3");
            this.Sueldo = sueldo;
        }
    }