Skip to content

This repository contains an example that shows how easy is to build a Strategy pattern using dependency injection with .NET

Notifications You must be signed in to change notification settings

karlospn/dotnet-strategy-pattern-using-dependency-injection

Repository files navigation

How to build a Strategy pattern using dependency injection with .NET

This repository contains an example that shows how easy is to build a Strategy pattern using dependency injection with .NET

Components

strategy-pattern

The classes and objects participating in this pattern include:

  • Strategy (IStrategy)

Declares a common interface to all concrete implementation must implement.

public interface IStrategy
{
    string Name { get; }
    string Execute(string message);
}
  • ConcreteStrategy (ReverseStrategy, ToLowerStrategy, ToUpperStrategy)

Every concrete strategy implements a single behaviour using the IStrategy interface

 public class ToUpperStrategy : IStrategy
{
    public string Name => nameof(ToUpperStrategy);
    public string Execute(string message)
    {
        return message.ToUpper();
    }
}
  • Context (StrategyContext)

Uses the ctor injection to obtain an IEnumerable that contain every IStrategy implementation.
It also has a method to execute a concrete IStrategy implementation.

public class StrategyContext : IStrategyContext
{
    private readonly IEnumerable<IStrategy> _strategies;
    public StrategyContext(IEnumerable<IStrategy> strategies)
    {
        _strategies = strategies;
    }

    public string ExecuteStrategy(
        string strategyName, 
        string message)
    {
        var instance = _strategies.FirstOrDefault(x =>
            x.Name.Equals(strategyName, StringComparison.InvariantCultureIgnoreCase));

        return instance is not null ?
            instance.Execute(message) :
            string.Empty;
    }
}

How to register the strategies into the DI container

The easiest way to register every strategy behavior in our DI (Dependency Injection) container is to do it like this:

builder.Services.AddTransient<IStrategy, ToUpperStrategy>();
builder.Services.AddTransient<IStrategy, ToLowerStrategy>();
builder.Services.AddTransient<IStrategy, ReverseStrategy>();

However, every time we want to add a new behavior to our Strategy pattern, we must remember to register it.

A better option is to use a bit of Reflection. This way, we can create as many behaviors as we want, and they will always be registered in the DI container.

var strategies = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(assembly => assembly.GetTypes())
                .Where(type => typeof(IStrategy).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract);

foreach (var strategy in strategies)
{
    builder.Services.AddTransient(
        typeof(IStrategy), 
        strategy);
}

How does it work

It's really simple.

  • Register every Strategy behaviour (either manually or using Reflection).
builder.Services.AddTransient<IStrategy, ToUpperStrategy>();
builder.Services.AddTransient<IStrategy, ToLowerStrategy>();
builder.Services.AddTransient<IStrategy, ReverseStrategy>();
  • In the StrategyContext class, the multiple IStrategy implementations we have registered are resolved into an IEnumerable<IStrategy>.

  • Now, we can filter the collection of IStrategy to execute the desired behaviour.

public class StrategyContext : IStrategyContext
{
    private readonly IEnumerable<IStrategy> _strategies;

    public StrategyContext(IEnumerable<IStrategy> strategies)
    {
        _strategies = strategies;
    }

    public string ExecuteStrategy(
        string strategyName, 
        string message)
    {
        var instance = _strategies.FirstOrDefault(x =>
            x.Name.Equals(strategyName, StringComparison.InvariantCultureIgnoreCase));

        return instance is not null ?
            instance.Execute(message) :
            string.Empty;
    }
}

About

This repository contains an example that shows how easy is to build a Strategy pattern using dependency injection with .NET

Topics

Resources

Stars

Watchers

Forks

Languages

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy