🎉 Hooray! After 3 years of work, I've finally released the ebook on design patterns! Check it out »

C#: Adapter

Adapter

Adapter is a structural design pattern, which allows incompatible objects to collaborate.

Adapter acts as a wrapper between two objects, It catches calls for one object and transforms them to format and interface recognizable by the second object.

Learn more about Adapter

Application of the pattern in C#

Complexity:

Popularity:

Usage examples: The Adapter pattern is pretty common in C# code. It’s very often used in systems based on some legacy code. In such cases, Adapters make legacy code with modern classes.

Identification: Adapter is recognizable by a constructor which takes an instance of different abstract/interface type. When adapter receives a call to any of its methods, it translates parameters to appropriate format and then directs the call to one or several methods of the wrapped object.

Example: Structure of the Pattern

This example illustrates the structure of the Adapter design pattern. It focuses on answering these questions:

  • What classes does it consists of?
  • What roles do these classes play?
  • In what way the elements of the pattern are related?

Program.cs: Structural Example

using System;

namespace RefactoringGuru.DesignPatterns.Adapter.Structural
{
    // / <summary>
 / EN: Adapter Design Pattern
 /
 / Converts the interface of
    // a class into the interface clients expect.
 / Adapter lets classes work
    // together where they otherwise couldn't, due to incompatible interfaces.
    // / 
 / RU: Паттерн Адаптер
 / 
 / Преобразует интерфейс одного класса к
    // интерфейсу другого класса.
 / Адаптер позволяет классам работать друг с
    // другом, даже если их интерфейсы несовместимы.
 / </summary>


    // / <summary>
 / EN: ITarget defines interface expected by the client.
 /
    // / RU: ITarget определяет интерфейс, с которым может работать клиент.
 /
    // </summary>
    interface ITarget
    {
        string GetRequest();
    }

    // / <summary>
 / EN: The Adaptee contains some useful behavior, but its
    // interface is incompatible
 / with the existing client code.The Adaptee
    // needs some adaptation before the client code can use it.
 / 
 / RU: Класс
    // Adaptee содержит полезные методы, но его интерфейс несовместим с тем,
    // который
 / ожидается клиентом. Интерфейс Adaptee требует некоторой
    // адаптации для того,
 / чтобы клиент мог его использовать.
 / </summary>
    class Adaptee
    {
        public string GetSpecificRequest()
        {
            return "Specific request.";
        }
    }

    // / <summary>
 / EN: The Adapter makes the Adaptee's interface compatible
    // with the ITarget interface. 
 / 
 / RU: Адаптер позволяет привести
    // интерфейс Adaptee к ожидаемому клиентом интерфейсу ITarget.
 / </summary>
    class Adapter : ITarget
    {
        private readonly Adaptee _adaptee;

        public Adapter(Adaptee adaptee)
        {
            _adaptee = adaptee;
        }

        public string GetRequest()
        {
            return $"This is '{_adaptee.GetSpecificRequest()}'";
        }
    }

    class Client
    {
        public void Main()
        {
            Adaptee adaptee = new Adaptee();

            ITarget target = new Adapter(adaptee);

            Console.WriteLine("Adaptee interface is incompatible with the client.");
            Console.WriteLine("But with adapter client can call it's method.");

            Console.WriteLine(target.GetRequest());
        }
    }

    class Program
    {
        static void Main()
        {
            new Client().Main();
        }
    }
}

Output.txt: Output

Adaptee interface is incompatible with the client.
But with adapter client can call it's method.
This is 'Specific request.'