Decorator pattern .net 6 C#

Çağdaş Erman Afacan
3 min readDec 8, 2022

The decorator pattern is a design pattern that allows you to add new behavior to existing objects dynamically. This is done by wrapping the original object with a new object that provides the additional behavior. The new object, called a decorator, conforms to the same interface as the original object so that it can be used in the same way.

Here is an example of the decorator pattern in C#:

// The interface for our objects
public interface IPizza
{
string GetDescription();
double GetCost();
}

// The base class for our pizzas
public class BasicPizza : IPizza
{
public string GetDescription()
{
return "Basic pizza";
}

public double GetCost()
{
return 10.0;
}
}

// A decorator class that adds extra cheese to a pizza
public class ExtraCheeseDecorator : IPizza
{
private IPizza _pizza;

public ExtraCheeseDecorator(IPizza pizza)
{
_pizza = pizza;
}

public string GetDescription()
{
return _pizza.GetDescription() + ", extra cheese";
}

public double GetCost()
{
return _pizza.GetCost() + 2.0;
}
}

// A decorator class that adds extra pepperoni to a pizza
public class ExtraPepperoniDecorator : IPizza
{
private IPizza _pizza;

public ExtraPepperoniDecorator(IPizza pizza)
{
_pizza = pizza;
}

public string GetDescription()
{
return _pizza.GetDescription() + ", extra pepperoni";
}

public double GetCost()
{
return _pizza.GetCost() + 3.0;
}
}

// Usage

var pizza = new BasicPizza();

// Basic pizza, 10.0
Console.WriteLine(pizza.GetDescription() + ", " + pizza.GetCost());

pizza = new ExtraCheeseDecorator(pizza);

// Basic pizza, extra cheese, 12.0
Console.WriteLine(pizza.GetDescription() + ", " + pizza.GetCost());

pizza = new ExtraPepperoniDecorator(pizza);

// Basic pizza, extra cheese, extra pepperoni, 15.0
Console.WriteLine(pizza.GetDescription() + ", " + pizza.GetCost());

In the example above, the BasicPizza class represents a basic pizza, and the ExtraCheeseDecorator and ExtraPepperoniDecorator classes add extra cheese and pepperoni to a pizza, respectively. The decorator classes implement the same interface as the BasicPizza class so that they can be used interchangeably. The decorator objects are created by passing the original object to the decorator’s constructor, and the decorator’s behavior is added on top of the original object’s behavior.

You can use the decorator pattern to add new behavior to an object without changing the object’s class, which can make your code more flexible and maintainable.

To register a decorator class with dependency injection in .NET 6, you can use the AddDecorator method on the IServiceCollection interface. Here is an example of how to register a decorator class with dependency injection in .NET 6:

public void ConfigureServices(IServiceCollection services)
{
// Register the base service
services.AddTransient<IService, Service>();

// Register the decorator class
services.AddDecorator<IService, ServiceDecorator>();
}

In the example above, the Service class is the base service that implements the IService interface. The ServiceDecorator class is a decorator that adds new behavior to the Service class, and it also implements the IService interface. The AddTransient method is used to register the Service class with the dependency injection container, and the AddDecorator method is used to register the ServiceDecorator class as a decorator for the Service class.

When you resolve the IService interface from the dependency injection container, you will get an instance of the ServiceDecorator class that wraps an instance of the Service class. This allows the ServiceDecorator class to add new behavior to the Service class without changing the Service class itself.

For more information about using the decorator pattern with dependency injection in .NET, see the Decorator pattern with dependency injection in ASP.NET Core documentation.

--

--