A method can depend on an interface instead of one concrete class.

dependency inversion Dependency inversion passes behavior through an abstraction.

Dependency Inversion

units
DependencyInversion.cs
Replay: real traced execution (multi-file project)
using System;

interface IRatePlan
{
    int Cost(int units);
}

class BasicPlan : IRatePlan
{
    public int Cost(int units)
    {
        return units * 2;
    }
}

class PremiumPlan : IRatePlan
{
    public int Cost(int units)
    {
        return units * 3;
    }
}

class Invoice
{
    public int Total(IRatePlan plan, int units)
    {
        return plan.Cost(units);
    }
}

class Program
{
    static void Main()
    {
        int units = 4;
        Invoice invoice = new Invoice();
        IRatePlan plan = new PremiumPlan();
        int total = invoice.Total(plan, units);

        Console.WriteLine($"units={units}");
        Console.WriteLine($"total={total}");
    }
}
using System;

interface IRatePlan
{
    int Cost(int units);
}

class BasicPlan : IRatePlan
{
    public int Cost(int units)
    {
        return units * 2;
    }
}

class PremiumPlan : IRatePlan
{
    public int Cost(int units)
    {
        return units * 3;
    }
}

class Invoice
{
    public int Total(IRatePlan plan, int units)
    {
        return plan.Cost(units);
    }
}

class Program
{
    static void Main()
    {
        int units = 2;
        Invoice invoice = new Invoice();
        IRatePlan plan = new PremiumPlan();
        int total = invoice.Total(plan, units);

        Console.WriteLine($"units={units}");
        Console.WriteLine($"total={total}");
    }
}
using System;

interface IRatePlan
{
    int Cost(int units);
}

class BasicPlan : IRatePlan
{
    public int Cost(int units)
    {
        return units * 2;
    }
}

class PremiumPlan : IRatePlan
{
    public int Cost(int units)
    {
        return units * 3;
    }
}

class Invoice
{
    public int Total(IRatePlan plan, int units)
    {
        return plan.Cost(units);
    }
}

class Program
{
    static void Main()
    {
        int units = 6;
        Invoice invoice = new Invoice();
        IRatePlan plan = new PremiumPlan();
        int total = invoice.Total(plan, units);

        Console.WriteLine($"units={units}");
        Console.WriteLine($"total={total}");
    }
}
  1. units ← 4, invoice ← Invoice, plan ← PremiumPlan

    33{34    static void Main()35    {36        int units→ 4 = 4; //@units=2, 637        Invoice invoice→ Invoice = new Invoice();38        IRatePlan plan→ PremiumPlan = new PremiumPlan();39        int total = invoiceInvoice.Total(planPremiumPlan, units4);
  2. public int Total(IRatePlan plan, int units)

    25{26    public int Total(IRatePlan planPremiumPlan, int units4)27    {28        return planPremiumPlan.Cost(units4);29    }
  3. public int Cost(int units)

    17{18    public int Cost(int units4)19    {20        return units4 * 3;21    }
  4. total ← 12

    38    IRatePlan plan = new PremiumPlan();39    int total→ 12 = invoiceInvoice.Total(planPremiumPlan, units4);4041    Console.WriteLine($"units={units4}");42    Console.WriteLine($"total={total12}");43}
    outputunits=4
    total=12
  1. units ← 2, invoice ← Invoice, plan ← PremiumPlan

    33{34    static void Main()35    {36        int units→ 2 = 2;37        Invoice invoice→ Invoice = new Invoice();38        IRatePlan plan→ PremiumPlan = new PremiumPlan();39        int total = invoiceInvoice.Total(planPremiumPlan, units2);
  2. public int Total(IRatePlan plan, int units)

    25{26    public int Total(IRatePlan planPremiumPlan, int units2)27    {28        return planPremiumPlan.Cost(units2);29    }
  3. public int Cost(int units)

    17{18    public int Cost(int units2)19    {20        return units2 * 3;21    }
  4. total ← 6

    38    IRatePlan plan = new PremiumPlan();39    int total→ 6 = invoiceInvoice.Total(planPremiumPlan, units2);4041    Console.WriteLine($"units={units2}");42    Console.WriteLine($"total={total6}");43}
    outputunits=2
    total=6
  1. units ← 6, invoice ← Invoice, plan ← PremiumPlan

    33{34    static void Main()35    {36        int units→ 6 = 6;37        Invoice invoice→ Invoice = new Invoice();38        IRatePlan plan→ PremiumPlan = new PremiumPlan();39        int total = invoiceInvoice.Total(planPremiumPlan, units6);
  2. public int Total(IRatePlan plan, int units)

    25{26    public int Total(IRatePlan planPremiumPlan, int units6)27    {28        return planPremiumPlan.Cost(units6);29    }
  3. public int Cost(int units)

    17{18    public int Cost(int units6)19    {20        return units6 * 3;21    }
  4. total ← 18

    38    IRatePlan plan = new PremiumPlan();39    int total→ 18 = invoiceInvoice.Total(planPremiumPlan, units6);4041    Console.WriteLine($"units={units6}");42    Console.WriteLine($"total={total18}");43}
    outputunits=6
    total=18